究竟什么是TickObject以及如何防止它成为内存泄漏?

时间:2015-12-13 19:55:47

标签: node.js memory-leaks

我在一些脚本中已经注意到了这几次。主要是围绕数组迭代和操作的脚本。

我一直看到大量内存泄漏,最终导致脚本耗尽内存并死机。检查后,它似乎是由大量的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`);
}

运行此选项,您将很快耗尽内存。这种行为是期待的吗? (我假设不是)或者它只是节点的奇怪行为?

1 个答案:

答案 0 :(得分:3)

解决了这个问题。阵列是一个红色的鲱鱼,实际上问题是process.stdout.write

每次写入时,afterWrite清理函数每次都是being queued up作为TickObject。因为我们永远不会离开我们所处的Tick /上下文,所以这只是积累直到节点爆炸。解?使任何长/永远运行的代码块与tick同步。

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);
})();

胜利!