Nodejs setTimeout утечка памяти?

v0.10.4

Вот простой цикл, который приводит к постоянно растущему использованию памяти:

function redx(){
      setTimeout(function(){ redx() },1000);
      console.log('loop');
}

redx();

Что я делаю неправильно?

ИЗМЕНИТЬ

ОК, просто попробовал предложение ссылаться на объект тайм-аута в области видимости, и кажется, что сбор мусора вызывается через примерно 40 секунд, здесь сокращены журналы из TOP:

3941 корень 20 0 32944 7284 4084 S 4,587 3,406 0: 01,32 node
 3941 корень 20 0 32944 7460 4084 S 2,948 3,489 0: 01,59 node
 3941 корень 20 0 32944 7516 4084 S 2,948 3,515 0: 01,68 node
 3941 корень 20 0 33968 8400 4112 S 2,948 3,928 0: 02,15 node
 3941 корень 20 0 33968 8920 4112 S 3.275 4.171 0: 02.98 node
 3941 корень 20 0 33968 8964 4112 S 2.948 4.192 0: 03.07 node
 3941 корень 20 0 33968 9212 4112 S 2,953 4,308 0: 03,16 node
 3941 корень 20 0 33968 9212 4112 S 2,953 4,308 0: 03,25 node
 3941 корень 20 0 33968 9212 4112 S 3.276 4.308 0: 03.35 node
 3941 корень 20 0 33968 9212 4112 S 2,950 4,308 0: 03,44 node

Ответ 1

Не знаю, почему, но, по-видимому, если вы ссылаетесь на объект тайм-аута в области функции nodejs, он правильно выполнит сбор мусора.

function redx(){
      var t = setTimeout(function(){ redx() },50);
      console.log('hi');
}

redx();

Ответ 2

Собственно, я думаю, что это может быть так, как работает сборщик мусора V8.

В моей системе куча node имеет тенденцию увеличиваться до 48 Мбайт, а затем стабилизируется, поэтому я думаю, что если вы продолжаете работать в течение долгого времени, потребление памяти в конечном итоге стабилизируется.

Вы можете получить информацию о том, когда/как запускается GC, запустив node с одним из параметров командной строки V8: флаг -trace_gc.

В ваших первых попытках с Redis вы систематически подключались/отключались от Redis при каждом вызове. Это, как правило, создает мусор. Вы должны открыть соединение один раз и использовать его много раз. Тем не менее, даже когда я это делаю, потребление памяти имеет тенденцию к стабилизации. Вот эволюция потребления памяти в этом примере с помощью Redis:

// something close to your initial function (when Redis was still in the picture)
function redx(){
    var client = redis.createClient();
    client.get("tally", function(err, reply) {
        client.quit();
    });
    setTimeout(function(){ redx() }, 50 );
}

Evolution of memory consumption with Redis connect/disconnect

Здесь стабилизация после 60 МБ кажется вполне очевидной.