Hello Everyone!
Not long ago I started using the latest version (3.1.0) of Node-Red with Node v18.18.2, and I noticed that a memory leak appeared on my devices (Raspberry Pi 3+, Orange Pi PC+). After about a week of use, my devices restarts due to lack of memory. Before the update I was using version 3.0.2.
I compared the dumps (after boot vs after 5 days) and saw that most of the memory is occupied by the objects that I save through the functions context.set / flex.set / global.set.
Can someone tell me how to properly use these context.set / flex.set / global.set functions and what is not recommended to do when using them? I read the documentation, but there is no description of what it is not recommended to do.
It's not array, it's just object with few fields and another objects.
Code example:
// myObj - created in another function:
var myObj = global.get('myObj');
var myObjPrev = context.get('myObjPrev') || myObj;
// compare current and previus obj and to do something...
// deep copy object
context.set( 'myObjPrev', JSON.parse(JSON.stringify(myObj)) )
// Sometimes I use Lodash
context.set( 'myObjPrev', _.cloneDeep(myObj) );
Of course, I understand that if it were an array, I would need to monitor its size, but in my case it is only an object that is overwritten with a new object (cloned) every time it is called.
Do I understand correctly that before calling a function context.set I need to delete the object (myObjPrev = undefined )?
No, you should not need to do that. The memory should automatically be freed when there are no remaining references to the data.
I have just run an intensive test using a 1MB Buffer, cloning it as you do and storing in context. This is repeated 10 times per second and over a significant time I saw no increase in memory usage.
If you run top while node-red is running do you see the memory used by node-red increasing?
When using top, the 'avail Mem' figure tells you the total amount of memory available for re-use.
What else do your flows do? Do you have contrib nodes in use? Are you working with database(s)? Are you making HTTP requests & how frequently? How frequent are you writing to context? Do you have loops in your flows?
Lastly, I would recommend you use the built-in util for cloning const clone = RED.util.cloneMessage(myObj)
It is perfectly normal to see Node-RED memory increase over time and then reduce as this is how the garbage collection process works. Node.js only recovers memory when it needs to.