什么是TickObject,如何防止其成为内存泄漏?

4
我在我的几个脚本中已经注意到了这个问题。主要是集中在数组迭代和操作的脚本上。
我一直看到巨大的内存泄漏,最终导致脚本耗尽内存并死亡。经过检查,似乎是由于创建了大量的TickObjects而没有清理所导致的。
一些阅读让我认为TickObject是节点的内部功能,用于管理异步事件。它们实际上是用来做什么的?为什么会失控?如何预防?
如果有帮助的话,这里是一个转储(警告:约312mb)https://www.dropbox.com/s/57t70t2igpo8kbi/heapdump-604700798.654094.heapsnapshot?dl=0,其中一个例子失控了。
编辑:
设法简化了有问题的代码。奇怪的是,看起来是使用process.stdout.write的组合?
var a = Array(100)
    .fill()
    .map(_ => Math.round(Math.random()) ? true : false),
    i = 0;

while (true) {
    a.map(_ => !_);
    process.stdout.write(`#${++i}\r`);
}

运行这个程序,你很快就会耗尽内存。这种行为是否可以预期?(我认为不是)还是只是Node的奇怪行为?
1个回答

9
工作出来了。数组是一个误导,实际问题是process.stdout.write
每次写入时,一个afterWrite清理函数被排队作为一个TickObject。由于我们从未离开Tick/上下文,这只会不断增加,直到node爆炸。解决方案?使任何长时间/永久运行的代码块也异步化处理。
var a = Array(100)
    .fill()
    .map(_ => Math.round(Math.random()) ? true : false),
    i = 0;

(function whileLoop () {
    a.map(_ => !_);
    process.stdout.write(`#${++i}\r`);

    process.nextTick(whileLoop);
})();

胜利!


感谢您的撰写 :) - Travis Kriplean

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