¿Cómo prevenir memory leaks en node.js?

Sabemos que node.js nos proporciona gran poder pero con gran poder viene una gran responsabilidad.

Hasta donde yo sé, el motor V8 no hace ninguna recolección de basura. Entonces, ¿cuáles son los errores más comunes que debemos evitar para asegurarnos de que no se escapa la memoria de mi servidor de nodo.

EDITAR: Lo siento por mi ignorancia, V8 tiene un poderoso recolector de basura.

Hasta donde yo sé, el motor V8 no hace ninguna recolección de basura.

V8 tiene un colector de basura poderoso e inteligente en construcción.

Su problema principal no es comprender cómo los cierres mantienen una referencia al scope y contexto de las funciones externas. Esto significa que hay varias formas de crear referencias circulares o crear variables que simplemente no se limpian.

Esto se debe a que su código es ambiguo y el comstackdor no puede decir si es seguro que la basura lo recopile.

Una forma de forzar al GC a recoger datos es anulando sus variables.

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

¿Cómo sabe v8 si es seguro que la basura recolecte objetos grandes cuando está en un controlador de eventos? No es así, necesita decir que ya no se usa al establecer la variable como nula.

Varios artículos para leer:

Quería convencerme de la respuesta aceptada, específicamente:

sin entender cómo los cierres mantienen una referencia al scope y contexto de las funciones externas.

Así que escribí el siguiente código para demostrar cómo las variables pueden no ser limpiadas, lo que las personas pueden encontrar de interés.

Si ha visto watch -n 0.2 'ps -o rss $(pgrep node)' ejecutándose en otro terminal, puede ver que se está produciendo una fuga. Tenga en cuenta cómo los comentarios en el buffer = null o el uso de nextTick permitirán completar el proceso:

 (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'); }); }()); 

recolección de basura activa con:

 node --expose-gc test.js 

y usar con:

 global.gc(); 

Happy Coding 🙂