Утечка памяти в файле node.js? - PullRequest
8 голосов
/ 14 января 2012

Я вижу утечку памяти с помощью следующего кода:

while (true) {
  console.log("Testing.");
}

Я попытался определить строку и просто использовать константу, но она приводит к утечке памяти, тем не менее:

var test = "Testing.";
while (true) {
  console.log(test);
}

Та же утечка происходит, если я использую файл вместо стандартного журнала:

var test = "Testing.";
var fh = fs.createWriteStream("test.out", {flags: "a"});
while (true) {
  fh.write(test);
}

Я подумал, может быть, это потому, что я не закрывал файл должным образом, но я попробовал это и все еще видел утечку:

var test = "Testing";
while (true) {
  var fh = fs.createWriteStream("test.out", {flags: "a"});
  fh.end(test);
  fh.destroy();
  fh = null;
}

У кого-нибудь есть намеки на то, как я должен писать вещи без утечки памяти?

1 Ответ

10 голосов
/ 14 января 2012

Это происходит потому, что вы никогда не предоставляете узлу возможность обрабатывать события «успешной записи», поэтому они бесконечно выстраиваются в очередь. Чтобы дать узлу возможность обрабатывать их, вы должны позволить циклу событий делать одну итерацию время от времени. Это не будет течь:

function newLine() {
  console.log("Testing.");
  process.nextTick(newLine);
}
newLine();

В реальных случаях использования это не проблема, потому что вам почти никогда не приходится выписывать столько огромных объемов данных одновременно, чтобы это имело значение. И если это произойдет, время от времени повторяйте цикл обработки событий.

Однако есть и вторая проблема, связанная с трюком nextTick: запись выполняется асинхронно, и если консоль / файл / что-либо медленнее, чем узел, узел бесконечно буферизует данные до тех пор, пока вывод снова не освободится. Чтобы избежать этого, вам нужно будет прослушать событие drain после того, как вы напишете что-то - оно сообщит вам, когда канал снова будет свободен. Смотрите здесь: http://nodejs.org/docs/latest/api/streams.html#event_drain_

...