I was running my server with pm2 start ...
and pm2 monit
was showing me 3GB memory
after 2 hours. So I attached memwatch, now I waited for another 2 hours and again the memory shown by pm2 monit
reached 3GB
.
So, I checked the logs memwatch generated. Showed me:
{ before: { nodes: 75659, size_bytes: 11141702, size: '10.63 mb' },
after: { nodes: 73226, size_bytes: 10840598, size: '10.34 mb' },
change:
{ size_bytes: -301104,
size: '-294.05 kb',
freed_nodes: 5141,
allocated_nodes: 2708,
And another:
{ before: { nodes: 72591, size_bytes: 10728318, size: '10.23 mb' },
after: { nodes: 73284, size_bytes: 10798062, size: '10.3 mb' },
change:
{ size_bytes: 69744,
size: '68.11 kb',
freed_nodes: 5931,
allocated_nodes: 6620,
Now I am really confused, those are the last logs so I'm pretty sure those are the logs generated when pm2 monit
showed the huge memory leak.
So, why is memwatch
showing me 10MB+
memory and pm2 monit showing 3GB+
?
Now switching to something like forever
or monit to see if the leak still exists.
A bit more background
PM2 is a Node. js process manager that comes with a built-in load balancer. It helps facilitate production deployments and enables you to keep running applications alive indefinitely (even when accidents occur).
Circular references are a common cause of memory leaks. Internet Explorer 6 and 7 are known to have reference-counting garbage collectors, which have caused memory leaks with circular references. No modern engine uses reference-counting for garbage collection anymore.
PM2 is a production process manager for Node. js applications with a built-in load balancer. It allows you to keep applications alive forever, to reload them without downtime and to facilitate common system admin tasks.
pm2 start app.js --node-args='--expose-gc'
Above argument --expose-gc will allow us to force call garbage collector from node js, now use following code for force garage collection.
if (global.gc) {
global.gc();
} else {
console.log('Garbage collection unavailable. use --expose-gc '
+ 'when launching node to enable forced garbage collection.');
}
This will solve PM2 meomry leak problem.
There are a lot of really bad answers on this thread. Really, really bad.
The answer is simple: your code has a memory leak that you need to find and remove, and it's VERY UNLIKELY that the GC is wrong, it's far more likely your code is the culprit.
So first off:
Secondly, the actual solution should be:
Profile your code's memory and CPU usage using the tool of your choice. For most people, that is going to be Chrome's debugging tools connected to the running node instance, and look at which functions are causing memory usage to spike. Simply calling the GC manually is lazy because your code still has a leak but you're just telling V8 to constantly hoover up memory after your app leaks it, which is very lazy practice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With