Как предотвратить утечку памяти в 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 добавляет приятную функциональность для вашего приложения из "нуля", но для существующих, вы можете только молиться:)