Node.JS memory leak with PM2

2020-05-21 08:42发布

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

  • I have been trying to profile and find the leak and there isn't just any leak showing on the profiles.
  • The memwatch diff is started when a client connects and the difference is taken when the client disconnects.

3条回答
smile是对你的礼貌
2楼-- · 2020-05-21 09:07

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:

  1. "I found that with PM2 the garbage collector doesn't work" - this is patently nonsensical, PM2 runs node, which uses V8, which has its own garbage collector built-in. This isn't disabled just because you run PM2.
  2. "So until that is fixed call the GC" - No! Calling the GC manually is lazy if your code has leaks, you should fix them.
  3. "After removing pm2 there is no more memory leak for now." - No, you're simply not monitoring it in PM2; the leak will still be there, you just don't see the error because you're running it using node and not looking at the results.

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.

查看更多
Melony?
3楼-- · 2020-05-21 09:12
  • I was also facing the same issue, but after little research i found that nodejs is not calling the garbage collector when using pm2.
  • So, until PM2 fixes that issue temporary work around is force call garbage collector, using following

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.

查看更多
男人必须洒脱
4楼-- · 2020-05-21 09:25

There is no leak at all on application running with PM2

Memory usage over time of application managed by PM2

Same for PM2 itself:

PM2 Monitoring itself

查看更多
登录 后发表回答