【问题标题】:node.js v8 garbage collection doesn't seem to triggernode.js v8 垃圾收集似乎没有触发
【发布时间】:2015-04-03 22:53:04
【问题描述】:

我很困惑,因为我的应用程序正在泄漏内存。它是一个每分钟处理数十万个数据包的 tcp 服务器。我检查了代码,改进了它并分析了内存。

一切似乎都还好,在本地进行低流量测试实际上表明 gc 正确释放了内存。但是当在实时流量大的服务器上时,它不会。

所以我尝试使用expose-gc 选项并在每次断开连接时添加强制gc,现在我发现内存不再泄漏或者甚至每次都泄漏?

所以,我的结论是 gc 没有激活。我的服务器有 3GB 内存,而应用程序在短短几个小时内就吃掉了其中的 2.8GB。

现在使用强制 gc,应用程序不再泄漏。它维持着大约 200MB 的内存。

那么,我的问题是,为什么 gc 没有被触发?

【问题讨论】:

  • 您找到解决方案了吗?我也有同样的问题T_T
  • @MarsZhu 抱歉,我放弃了 Node,转而使用 Go,这是有史以来最好的决定。

标签: javascript node.js memory-leaks garbage-collection v8


【解决方案1】:

Source: StrongLoop Blog

垃圾收集解决的根本问题是识别死亡 无法访问的内存区域(无法访问的对象/垃圾) 通过来自活动对象的一些指针链。一次 确定后,这些区域可以重新用于新的分配或 释放回操作系统

使用事件侦听器时内存泄漏很常见,这是由于事件发射器(也是一个对象)保留对它的引用而阻止了正在侦听的对象被垃圾收集的情况。

所以在您的代码中onSuccess 方法将被您的请求对象引用。但是,onSuccess 只是一个函数,它被用作所有请求对象的侦听器,因此不会导致内存累积。

为了找出代码中对象保持活动状态的真正原因,我会检查连接结束并确保没有指针保持活动状态。 此外,在某些情况下,V8 不会在每次使用时都创建一个函数的实例,而这可能就是手头的情况。如果两者结合使用,您分配的内存将不断堆积回调实例。

在两次次要垃圾回收中幸存下来的对象将被提升 到“旧空间”。旧空间是在完整 GC 中收集的垃圾(主要 垃圾收集周期),频率要低得多。我假设这个 牵强附会,但您分配比清扫更快的选择 可能会考虑循环,因此当您触发垃圾时 手动收集,会触发一个完整的 GC 循环。

为了确保快速的对象分配、短的垃圾回收暂停,以及 “无内存碎片 V8”采用了 stop-the-world, 分代,准确,垃圾收集器。 V8 基本上停止了 执行完整的垃圾回收周期时执行程序。

这可以解释为什么V8强制进行垃圾清理时内存不会泄漏。

【讨论】:

  • 这很令人困惑,更不用说从 strongloops 博客中获取确切的段落了。
  • 是的,我很抱歉没有添加源代码。我通常会这样做。
  • 只有这个答案的最后一段与问题相关! “在两次小型垃圾收集中幸存下来的对象将被提升到“旧空间”。旧空间是在完整 GC(主要垃圾收集周期)中进行垃圾收集的,频率要低得多。我认为这很牵强,但是可能会考虑分配比清扫周期更快的选项,因此当您触发垃圾收集时手动触发一个完整的 GC 循环。”
【解决方案2】:

我注意到垃圾收集没有发生同样的问题。测试我的服务器将相同的内容(由 react 渲染)重复发送到测试脚本内存将在一个小时左右的时间内耗尽。此 AWS 实例只有 1GB RAM。

每当 heapUsed 超过 256MB 时强制进行垃圾收集后,一切都可以正常运行数小时。 heapUsed 在 GC 后从大约 150MB 波动到略高于 256MB。

同时 heapTotal 最终稳定在大约 340MB。

我的结论是我的服务器没有泄漏内存,垃圾收集没有按预期进行。

这是我的工作:

setInterval (function() {
    let mu = process.memoryUsage();
    console.log('heapTotal:',  mu.heapTotal, 'heapUsed:', mu.heapUsed);
    if (mu.heapUsed > 256 * 1024 * 1024) {
        console.log('Taking out the garbage');
        global.gc();
    }
}, 1000 * 60);

每次请求后检查内存可能会更好。

【讨论】:

  • mu.heapTotal 和 mu.heapUsed 是否返回 Bytes 值?
猜你喜欢
  • 2011-08-01
  • 2014-02-05
  • 2016-10-12
  • 1970-01-01
  • 2012-02-04
  • 2019-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多