NodeJS在无限循环中的内存消耗

时间:2011-10-26 10:11:34

标签: javascript node.js memory-leaks infinite-loop v8

我不知道这是否是Node或V8的错误,但如果我运行以下代码,则节点进程会泄漏内存。 GC似乎永远不会启动,并且在几秒钟内耗费了大约1GB的内存。这是出乎意料的行为。我错过了什么吗?

以下是代码:

for(;;) { console.log(1+1); }

显然,这是一个有点人为的情况,但我可以看到长时间运行过程中永远不会释放内存的问题。

编辑:我尝试了v0.5.10(不稳定)和v0.4.12(稳定版),不稳定版本执行得更好一点---稳定版本只是停止输出到控制台但继续消耗内存,而稳定版本继续执行并消耗内存而不会暂停。

3 个答案:

答案 0 :(得分:10)

您通过永远不会返回它来阻止node.js事件循环。

当您向流节点写入内容时.js异步执行此操作:它发送写入请求,在流的内部数据结构中对有关已发送请求的信息进行排队,并等待将通知其完成的回调。

如果阻塞事件循环,则永远不会调用回调(因为从不处理传入事件),并且永远不会释放在流中排队的辅助数据结构。

如果通过使用nextTick / setInterval / setTimeout不断调度自己的事件来“重载”事件循环,则可能会发生同样的情况。

答案 1 :(得分:6)

@VyacheslavEgorov的回答似乎正确,但我猜想推迟到事件循环可以解决问题。您可能想要比较无限for-loop与此无限循环策略的比较:

function loginf() {
  console.log(1+1);
  process.nextTick(loginf);
}
loginf();

我的想法是使用process.nextTick(cb)来推迟事件循环,并且(可能)允许GC完成它的工作。

答案 2 :(得分:5)

当Node.js v0.10已经发布时,setImmediate应该在调用递归回调时作为第一选择而不是process.nextTick

function loginf() {
  console.log(1+1);
  setImmediate(loginf);
}
loginf();

在我的计算机上运行约15分钟后,此代码块的内存消耗保持较低(<10MB)。

相反,运行无限for loop引起内存韭菜而process.nextTick引发了Maximum call stack size exceeded错误。

同时检查此Q&amp; A:setImmediate vs. nextTick