Как предотвратить утечку памяти в node.js?
Мы знаем, что node.js предоставляет нам большую силу, но с большой силой несет большую ответственность.
Насколько я знаю, двигатель V8 не делает сборку мусора. Итак, каковы наиболее распространенные ошибки, которые мы должны избегать, чтобы гарантировать отсутствие утечки памяти с моего сервера node.
EDIT:
Извините за мое невежество, у V8 есть мощный сборщик мусора.
Ответы
Ответ 1
Насколько я знаю, двигатель V8 не сделать любую сборку мусора.
V8 имеет мощный и интеллектуальный сборщик мусора в сборке.
Ваша основная проблема заключается не в понимании того, как замыкания поддерживают ссылку на объем и контекст внешних функций. Это означает, что вы можете создавать круговые ссылки или создавать другие переменные, которые просто не очищаются.
Это связано с тем, что ваш код неоднозначен, и компилятор не может определить, можно ли его мусор собирать.
Способ заставить GC собирать данные - обнулить переменные.
function(foo, cb) {
var bigObject = new BigObject();
doFoo(foo).on("change", function(e) {
if (e.type === bigObject.type) {
cb();
// bigObject = null;
}
});
}
Как v8 знает, безопасно ли мусор собирать большой объект, когда он находится в обработчике событий? Это не значит, что вам нужно сказать, что он больше не используется, установив переменную в значение null.
Различные статьи для чтения:
Ответ 2
Я хотел убедить себя в принятом ответе, в частности:
не понимает, как замыкания поддерживают ссылку на объем и контекст внешних функций.
Итак, я написал следующий код, чтобы продемонстрировать, как переменные не могут быть очищены, что люди могут найти интерес.
Если у вас есть watch -n 0.2 'ps -o rss $(pgrep node)'
, работающий в другом терминале, вы можете наблюдать, как происходит утечка. Обратите внимание, что комментирование в buffer = null
или с помощью nextTick
позволит завершить процесс:
(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');
});
}());
Ответ 3
активная сборка мусора с:
node --expose-gc test.js
и используйте с:
global.gc();
Счастливое кодирование:)
Ответ 4
Функция SBuffer v2 (статический буфер) - это все, что вам нужно для устранения утечек памяти Node.js, и это очень просто использовать.
npm install sbuffer
Пример: выделите 2 буфера 300 Мб каждый (всего 600 Мб) и 300/10 (30 Мбайт байт) для использования мусора. Таким образом, ваше приложение никогда не будет расти при использовании памяти, поскольку оно использует только выделенное пространство памяти на 600 МБ.
var SBuffer = require('sbuffer');
/* allocate 600Mb memory*/
var sb = SBuffer(2,3e8,10);
sb.t0 = '01';/* add a key t0 with string value 01 */
console.log(sb.t0);/* print: <Buffer 30 31> */
console.log(sb.t0.toString());/* print: 01 */
Тип входного значения должен быть непустым String
или Buffer
, а тип вывода - Buffer
или undefined
, если ключ не существует.
SBuffer добавляет приятную функциональность для вашего приложения из "нуля", но для существующих, вы можете только молиться:)