Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent memory leaks in node.js?

We know node.js provides us with great power but with great power comes great responsibility.

As far as I know the V8 engine doesn't do any garbage collection. So what are the most common mistakes we should avoid to ensure that no memory is leaking from my node server.

EDIT: Sorry for my ignorance, V8 does have a powerful garbage collector.

like image 797
neebz Avatar asked Apr 20 '11 16:04

neebz


People also ask

How do I stop memory leaks in node JS?

Avoid Accidental Globals This could be the result of a typo and could lead to a memory leak. Another way could be when assigning a variable to this within a function in the global scope. To avoid issues like this, always write JavaScript in strict mode using the 'use strict'; annotation at the top of your JS file.

Where is memory leak in node JS application?

Finding the leak. Chrome DevTools is a great tool that can be used to diagnose memory leaks in Node. js applications via remote debugging. Other tools exist and they will give you the similar.


2 Answers

As far as I know the V8 engine doesn't do any garbage collection.

V8 has a powerful and intelligent garbage collector in build.

Your main problem is not understanding how closures maintain a reference to scope and context of outer functions. This means there are various ways you can create circular references or otherwise create variables that just do not get cleaned up.

This is because your code is ambigious and the compiler can not tell if it is safe to garbage collect it.

A way to force the GC to pick up data is to null your variables.

function(foo, cb) {     var bigObject = new BigObject();     doFoo(foo).on("change", function(e) {          if (e.type === bigObject.type) {               cb();               // bigObject = null;          }     }); } 

How does v8 know whether it is safe to garbage collect big object when it's in an event handler? It doesn't so you need to tell it it's no longer used by setting the variable to null.

Various articles to read:

  • http://www.ibm.com/developerworks/web/library/wa-memleak/
like image 102
Raynos Avatar answered Sep 17 '22 20:09

Raynos


I wanted to convince myself of the accepted answer, specifically:

not understanding how closures maintain a reference to scope and context of outer functions.

So I wrote the following code to demonstrate how variables can fail to be cleaned up, which people may find of interest.

If you have watch -n 0.2 'ps -o rss $(pgrep node)' running in another terminal you can watch the leak occurring. Note how commenting in either the buffer = null or using nextTick will allow the process to complete:

(function () {     "use strict";      var fs = require('fs'),         iterations = 0,          work = function (callback) {             var buffer = '',                 i;              console.log('Work ' + iterations);              for (i = 0; i < 50; i += 1) {                 buffer += fs.readFileSync('/usr/share/dict/words');             }              iterations += 1;             if (iterations < 100) {                 // buffer = null;                  // process.nextTick(function () {                     work(callback);                 // });             } else {                 callback();             }         };      work(function () {         console.log('Done');     });  }()); 
like image 44
davetapley Avatar answered Sep 18 '22 20:09

davetapley