NodeJS内存消耗在无限循环中
我不知道这是一个与节点或V8的错误,但如果我运行下面的代码节点进程泄漏内存。 GC似乎从来没有踢过,在几秒钟内它消耗> 1GB的内存。 这是意想不到的行为。 我错过了什么吗?
代码如下:
for(;;) { console.log(1+1); }
很显然,这是一个有点人为的情况,但我可以看到一个长期运行的过程永远不会释放内存的问题。
编辑:我试了v0.5.10(不稳定)和v0.4.12(稳定),不稳定的版本performance更好一点 – 稳定版本只是停止输出到控制台,但继续消耗内存,而稳定版本继续执行并消耗内存而不会暂停。
你正在阻止node.js事件循环,永远不会返回它。
当你写一些东西给stream时,node.js是asynchronous执行的:它发送写入请求,在stream的内部数据结构中将有关发送请求的信息排队,并等待callback,通知它完成。
如果阻塞事件循环,则永远不会调用callback(因为传入的事件永远不会被处理),在stream中排队的辅助数据结构永远不会被释放。
如果通过使用nextTick / setInterval / setTimeout不断调度自己的事件来“重载”事件循环,则可能会发生同样的情况。
@VyacheslavEgorov的答案似乎是正确的,但我想推迟到事件循环将解决这个问题。 你可能想比较一下你的无限for-loop
与无限循环策略的比较:
function loginf() { console.log(1+1); process.nextTick(loginf); } loginf();
这个想法是使用process.nextTick(cb)
来推迟事件循环,并且(大概)让GC去做它的事情。
由于Node.js v0.10已经发布,在调用recursioncallbacksetImmediate
应该使用setImmediate
作为第一select而不是process.nextTick
。
function loginf() { console.log(1+1); setImmediate(loginf); } loginf();
在我的计算机上运行大约15分钟后,这段代码的内存消耗保持在很低的水平(<10MB)。
相反,运行无限for loop
导致内存韭菜和process.nextTick
抛出一个Maximum call stack size exceeded
错误。
请检查这个问答: setImmediate与nextTick