尽管堆大小相当一致,但 node.js RSS 内存会随着时间的推移而增长
Posted
技术标签:
【中文标题】尽管堆大小相当一致,但 node.js RSS 内存会随着时间的推移而增长【英文标题】:node.js RSS memory grows over time despite fairly consistent heap sizes 【发布时间】:2014-08-20 07:35:55 【问题描述】:我有一个 node.js 应用程序,尽管 heapUsed/heapTotal 保持相对恒定,但 RSS 内存使用量似乎一直在增长。
这是一周内进行的三个内存测量的图表(来自process.memoryUsage()
):
您可能会注意到存在某种周期性模式 - 这与应用程序每天的活动相对应。
实际上,堆似乎确实有轻微的增长,尽管它与 RSS 的增长相去甚远。所以我时不时地进行堆转储(使用 node-heapdump),并使用 Chrome 的堆比较功能来查找泄漏。 一个这样的比较可能如下所示(按大小增量降序排序):
实际显示的内容取决于拍摄快照的时间(例如,有时分配了更多的 Buffer 对象等) - 这里我尝试了一个最能说明问题的示例。
首先要注意的是左侧的大小(203MB 与 345MB)远高于图中显示的堆大小。其次,大小增量显然与 142MB 的差异不匹配。其实按照size delta升序排序,很多对象已经deallocated了,也就是说堆应该更小!
有没有人知道:
为什么会这样? (RSS 不断增长,堆大小稳定) 除了不时重新启动服务器之外,我如何才能阻止这种情况发生?其他细节: 节点版本:0.10.28 操作系统:Ubuntu 12.04,64 位
更新:正在使用的模块列表:
asyncv0.2.6 log4jsv0.6.2 mysqlv2.0.0-alpha7 nodemailer v0.4.4 node-time v0.9.2(用于时区信息,不要与节点时间混淆) sockjsv0.3.8 underscorev1.4.4 usage v0.3.9(用于 CPU 统计,不用于内存使用) webkit-devtools-agent v0.2.3(已加载但未激活)heapdump v0.2.0 在转储时加载。感谢阅读。
【问题讨论】:
您使用什么模块?他们中的任何一个都是编译的插件吗? 感谢您的评论,在上面添加了模块列表。我相信只有 node-time、webkit-devtools-agent 和 heapdump 是编译模块,只有 node-time 被积极使用。 node-time 的编译组件是一个非常简单的 time.h 包装器。 @zinga 你找到这是什么原因了吗?遇到同样的问题 不幸的是,当我更新到节点 v0.12 时问题实际上变得更糟,然后当我移到节点 v4 时问题就消失了。没有添加额外的编译模块,所以我将内存泄漏归咎于节点。如果您认为它不是编译模块,请尝试不同版本的节点我猜... 我们仍在调查类似的问题,但我们确实遇到了这个问题:通常,只有数组和字符串可以具有显着的浅大小。但是,字符串和外部数组通常主要存储在渲染器内存中,只在 javascript 堆上暴露一个小的包装对象。 Source can be found here 在 Shallow Size 部分下。 【参考方案1】:您看到的 RSS 使用和堆使用之间的区别在于缓冲区。
“缓冲区类似于整数数组,但对应于 V8 堆外的原始内存分配” https://nodejs.org/api/buffer.html#buffer_buffer
【讨论】:
感谢您的解释。缓冲区实际上显示在堆转储中(包括使用的空间),并且它们没有解释差异。肯定不会完全不同——node、V8 和其他原生代码自己消耗内存,这增加了 RSS 而不会增加 JS 堆大小。以上是关于尽管堆大小相当一致,但 node.js RSS 内存会随着时间的推移而增长的主要内容,如果未能解决你的问题,请参考以下文章
JVM 的堆大小不断增加(但 usedMemory() 不断减少)