在节点中手动运行垃圾收集

Bow*_* Su 10 node.js

我正在使用节点,我正在考虑在节点中手动运行垃圾收集.这有什么缺点吗?我这样做的原因是看起来节点没有经常运行垃圾收集.有谁知道V8在节点中执行垃圾收集例程的频率如何?

谢谢!

d4n*_*4n3 16

我实际上在使用1GB实例的heroku上运行节点时遇到了同样的问题.

在生产流量上运行节点服务器时,内存会不断增长,直到超出内存限制,从而导致内存运行缓慢.

这可能是由于应用程序生成了大量垃圾,它主要服务于JSON API响应.但它不是内存泄漏,只是未收集的垃圾.

似乎节点没有优先考虑在我的应用程序的旧对象空间上进行足够的垃圾收集,因此内存会不断增长.

手动运行global.gc()(使用节点--expose_gc启用)每次会减少50MB的内存使用量,并会暂停应用程序约400ms.

我最终做的是在一个随机的时间表上手动运行gc(这样heroku实例不会同时执行G​​C).这减少了内存使用量并停止了内存配额超出错误.

简化版本将是这样的:

function scheduleGc() {
  if (!global.gc) {
    console.log('Garbage collection is not exposed');
    return;
  }

  // schedule next gc within a random interval (e.g. 15-45 minutes)
  // tweak this based on your app's memory usage
  var nextMinutes = Math.random() * 30 + 15;

  setTimeout(function(){
    global.gc();
    console.log('Manual gc', process.memoryUsage());
    scheduleGc();
  }, nextMinutes * 60 * 1000);
}

// call this in the startup script of your app (once per process)
scheduleGc();
Run Code Online (Sandbox Code Playgroud)

您需要在暴露垃圾收集的情况下运行您的应用:

node --expose_gc app.js
Run Code Online (Sandbox Code Playgroud)


小智 5

我知道这对 OP 的帮助可能有点迟缓,但我想我会与我最近在 Node JS 内存分配和垃圾收集方面的经验合作。

我们目前正在开发一个在 raspberry pi 3 上运行的节点 JS 服务器。它时常会因为内存不足而崩溃。我最初认为这是内存泄漏,经过一个半星期的搜索我的代码却一无所获,我认为问题可能会因 Node JS 分配的内存多于 Rpi3 上可用的内存而加剧它在执行 GC 之前的进程。

我一直在使用以下命令运行我的服务器的新实例:

'节点 server.js --max-executable-size=96 --max-old-space-size=128 --max-semi-space-size=2'

这有效地限制了允许节点在本地机器上占用的空间总量,并强制更频繁地进行垃圾收集。到目前为止,我们看到内存的持续使用,它向我证实了我的代码最初没有泄漏,而是节点分配了比可能更多的内存。

编辑:这里的链接更具体地概述了我正在处理的问题。

- nodejs 减少 v8 垃圾收集器内存使用 - https://github.com/nodejs/node/issues/2738


Sac*_*acr 4

V8 当他认为有用时运行垃圾收集。对此没有固定的延迟。您可以阅读这篇文章来了解垃圾收集V8:https://strongloop.com/strongblog/node-js-performance-garbage-collection/

无论如何,在项目中手动运行垃圾收集器不是一个好主意,因为它完全阻塞了节点进程。因此在垃圾收集期间,您的程序将不会处理任何请求。