Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running garbage collection manually in node

Tags:

node.js

I am using node and am considering manually running garbage collection in node. Is there any drawbacks on this? The reason I am doing this is that it looks like node is not running garbage collection frequently enough. Does anyone know how often V8 does its garbage collection routine in node?

Thanks!

like image 492
Bowen Su Avatar asked Jun 05 '15 19:06

Bowen Su


2 Answers

I actually had the same problem running node on heroku with 1GB instances.

When running the node server on production traffic, the memory would grow constantly until it exceeded the memory limit, which caused it to run slowly.

This is probably caused by the app generating a lot of garbage, it mostly serves JSON API responses. But it wasn't a memory leak, just uncollected garbage.

It seems that node doesn't prioritize doing enough garbage collections on old object space for my app, so memory would constantly grow.

Running global.gc() manually (enabled with node --expose_gc) would reduce memory usage by 50MB every time and would pause the app for about 400ms.

What I ended up doing is running gc manually on a randomized schedule (so that heroku instances wouldn't do GC all at once). This decreased the memory usage and stopped the memory quota exceeded errors.

A simplified version would be something like this:

function scheduleGc() {
  if (!global.gc) {
    console.log('Garbage collection is not exposed');
    return;
  }

  // schedule next gc within a random interval (e.g. 15-45 minutes)
  // tweak this based on your app's memory usage
  var nextMinutes = Math.random() * 30 + 15;

  setTimeout(function(){
    global.gc();
    console.log('Manual gc', process.memoryUsage());
    scheduleGc();
  }, nextMinutes * 60 * 1000);
}

// call this in the startup script of your app (once per process)
scheduleGc();

You need to run your app with garbage collection exposed:

node --expose_gc app.js
like image 198
d4n3 Avatar answered Sep 20 '22 15:09

d4n3


I know this may be a bit of a tardy reply to help to OP, but i thought I would collaborate my recent experiences with Node JS memory allocation and garbage collection.

We are currently working on a node JS server running on a raspberry pi 3. Every so often it would crash due to running out of memory. I initially thought this was a memory leak, and after a week and a half of searching through my code and coming up with nothing, I thought the problem could have been exacerbated by the fact that Node JS allocates more memory than available on the Rpi3 for its processes before it does the GC.

I have been running new instances of my server with the following commands:

'node server.js --max-executable-size=96 --max-old-space-size=128 --max-semi-space-size=2'

This effectively limits the total amount of space that node is allowed to take up on the local machine and forces garbage collections to be done more frequently. Thus far, we are seeing a constant usage of memory and it confirms to me that my code was not leaking initially, but rather node was allocating more memory than possible.

EDIT: This link here outlines in more specific terms the issue I was dealing with.

-nodejs decrease v8 garbage collector memory usage -https://github.com/nodejs/node/issues/2738

like image 35
Henri De Boever Avatar answered Sep 18 '22 15:09

Henri De Boever