NodeJS 无限循环内存消耗

发布于 2024-12-11 20:30:46 字数 318 浏览 0 评论 0原文

我不知道这是否是 Node 或 V8 的错误,但如果我运行以下代码,节点进程会泄漏内存。 GC 似乎从未启动,并且在几秒钟内就消耗了超过 1GB 的内存。这是意想不到的行为。我错过了什么吗?

代码如下:

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

显然,这有点人为的情况,但我可以看到长期运行的进程永远不会释放内存的问题。

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

I don't know if this is a bug with Node or V8, but if I run the following code the node process leaks memory. The GC never seems to kick in and in a few seconds it's consuming >1GB of memory. This is unexpected behavior. Am I missing something?

Here's the code:

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

Obviously, this is a little bit of a contrived situation, but I can see an issue with a long-running process that would never free memory.

Edit: I tried both with v0.5.10 (unstable) and v0.4.12 (stable) and the unstable version performs a little bit better---the stable version just stops outputting to the console but continues to consume memory, whereas the stable version continues executing and consuming memory without pause.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怎言笑 2024-12-18 20:30:46

您通过从不返回来阻止 node.js 事件循环。

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

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

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

You are blocking node.js event loop by never returning to it.

When you write something to a stream node.js does that asynchronously: it sends the write request, queues information about sent request in the stream's internal data-structures and awaits the callback that would notify it about the completion.

If you are blocking event loop the callback will never be called (because incoming events are never processed) and auxiliary data structures queued in the stream will never be freed.

The same can probably happen if you "overload" event loop by constantly scheduling your own events with nextTick/setInterval/setTimeout.

稀香 2024-12-18 20:30:46

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

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

想法是使用 process.nextTick(cb) 推迟事件循环并(可能)允许 GC 执行其操作。

The answer by @VyacheslavEgorov seems right on but I would guess that deferring to the event loop would solve the problem. You might want to compare how your infinite for-loop compares to this infinite looping strategy:

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

The idea is to use process.nextTick(cb) to defer to the event loop and (presumably) allow the GC to do its thing.

隱形的亼 2024-12-18 20:30:46

随着 Node.js v0.10 的发布,setImmediate 应作为首选,而不是 process.nextTick

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

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

相反,运行无限 for 循环 会导致内存泄漏,并且 process.nextTick 引发超过最大调用堆栈大小 错误。

另请查看此问答:setImmediate 与 nextTick

As Node.js v0.10 has been released, setImmediate should be used as the first choice instead of process.nextTick when calling the recursive callback.

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

The memory consumption of this chunk of code kept low ( <10MB ) after running for about 15 mins on my computer.

On the contrary, Running the infinite for loop caused memory leek and the process.nextTick throwed an Maximum call stack size exceeded error.

Check this Q&A also: setImmediate vs. nextTick

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文