maj*_*rif 6 javascript garbage-collection memory-leaks v8 node.js
我很困惑,因为我的应用程序泄漏了内存.它是一个tcp服务器,每分钟处理数十万个数据包.我检查了代码,对其进行了改进并对内存进行了分析.
一切似乎都没问题,以低流量在本地测试实际上表明gc正确释放内存.但是当在现场繁忙的交通服务器上它没有.
所以我尝试使用该expose-gc选项并将强制gc添加到每次断开连接,现在我发现内存不再泄漏或者是否每次都泄漏?
所以,我的结论是gc没有激活.我的服务器有3GB的内存,应用程序在短短几个小时就可以吃掉2.8GB的内存.
现在使用强制gc,应用程序不再泄漏.它维持大约200MB的内存.
所以,我的问题,为什么gc不会被触发?
\n\n\n垃圾收集解决的基本问题是识别死内存区域(无法访问的对象/垃圾),这些区域无法通过活动对象的某些指针链访问。一旦确定,这些区域可以重新用于新的分配或释放回操作系统
\n
使用事件侦听器时内存泄漏非常常见,这是由于正在侦听的对象无法被垃圾收集的情况引起的,因为事件发射器(也是一个对象)保留了对其的引用。
\n\n因此,在您的代码中,onSuccess方法将由您的请求对象引用。但是,这onSuccess只是一个被重用为所有请求对象的侦听器的函数,因此不会导致内存堆积。
为了找到代码中对象保持活动状态的真正原因,我会检查连接结束并确保没有指针保持活动状态。\n此外,在某些情况下 V8 不会创建函数的实例每次使用的时候,手上都可能出现这样的情况。如果两者结合起来,您分配的内存将继续堆积回调的实例。
\n\n\n\n\n在两次次要垃圾回收中幸存下来的对象将提升\n 到 \xe2\x80\x9cold-space。\xe2\x80\x9d 旧空间在完整 GC(主要\n 垃圾回收周期)中进行垃圾回收,这要少得多频繁。我认为这是牵强的,但是可以考虑分配比扫描周期更快的选项,因此当您手动触发垃圾收集时,会触发完整的 GC 周期。
\n\n为了确保快速的对象分配、短暂的垃圾收集暂停,\n\xe2\x80\x9cno 内存碎片 V8\xe2\x80\x9d 采用了一个停止世界的、\n 分代的、准确的垃圾收集器。当执行完整的垃圾收集周期时,V8 本质上会停止程序执行。
\n
这可以解释为什么当V8强制进行垃圾清理时内存不会泄漏。
\n