Node.js文件内存泄漏?

9

我看到以下代码存在内存泄漏:

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

这是因为你从未给Node机会处理“写入成功”的事件,因此它们无限排队。要给Node处理这些事件的机会,你需要偶尔让事件循环执行一次迭代。这样就不会发生资源泄漏:

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

在实际使用中,这并不是问题,因为你几乎从来不需要一次性写出如此巨大的数据量,这并不重要。如果确实存在问题,则可以定期循环事件循环。

然而,这也有第二个问题,与nextTick技巧相同:写入是异步的,如果控制台/文件/其他比node慢,node将无限缓冲数据,直到输出再次空闲为止。为避免这种情况,在写入一些内容后,您必须监听drain事件 - 它告诉您管道何时再次空闲。请参见此处:http://nodejs.org/docs/latest/api/streams.html#event_drain_


我能够使用文件处理程序(fs.createWriteStream)复现您的解决方案,但如果我尝试使用 console.log,我仍然会遇到内存泄漏问题。function writeConsole() { console.log("test"); if (typeof(gc) == "function") gc(); process.nextTick(writeConsole); } writeConsole();当我使用 node test.js 运行上述代码块时,我发现每次迭代都会使我的内存使用量增加。当我将其作为 node --expose-gc test.js 运行时,我没有看到任何持续增加的情况。 - facetious
@facetious:它不会太频繁地进行GC循环,否则将会是低效的。让它运行一段时间,你会发现内存使用量最终会降到起始水平。 - thejh
@facetious:我甚至还记得自己尝试过这个 - 我用gnuplot制作了一个内存使用图表,如果我没记错的话,它总是在一段时间内增加,然后回落到大约开始值。 - thejh
1
我的内存会随着时间的推移而不断降低,直到我重新启动节点进程。:( - facetious

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接