NodeJS v14 内存问题:Resident Set 增长很多

NodeJS v14 memory issues: Resident Set grows a lot

将 NodeJS 服务器应用程序从 v6 升级到 v14 后,我遇到了奇怪的内存行为。

我在使用 Dynatrace 分析内存使用情况时注意到了这个问题(如果是的话):

  1. 过程没有问题,也没有重启,也没有遇到失败:一切正常

  2. 总内存使用量不断增加,直到达到大约 5GB(我们在 运行 应用程序时使用了 --max-memory-restart 5G 选项 - 谁知道它是否与它有关...)

  3. 堆大小有其通常的值并保持稳定在 100~150MB 左右

  4. Resident Set 不断增长,直到达到 5GB 并且从未超过此上限(此外:重启安全选项功能从未被触发)

  5. 我只在 NodeJS v14 中遇到这个“问题”,在 NodeJS v6 中没有,应用程序基本代码是相同的

这里有一些关于内存使用的详细信息:

我对 JS Engine V8 内存结构和使用不是很了解,但是我阅读了以下讲座:

尽管有这些很棒的讲座,但我完全不相信是什么原因导致此 Resident Set 内存以这种方式增长。既然它没有给我带来任何实际问题,我可以掩饰吗?或者我应该加深,如果是的话,你建议我做什么?

I upgraded a NodeJS server application from V4 to V8. [...] I encounter this "issue" only in V8, not in V4

术语澄清:Node 的每个版本都是围绕 V8 JavaScript engine 构建的(它本身的版本目前恰好是 8.x,但这与其名称不同:之前我们有 V8 v7.x,很快我们就会有 V8 v9.x)。

如果您确实是说您刚刚从 Node 版本 4.x 更新到 Node 版本 8.x,那么请进一步更新:至少到 Node 版本 12.x,even better 14.x.

我不熟悉 Dynatrace,但这些图表有点令人困惑。没有“V8 堆内存的驻留集大小”这样的东西:整个 进程 有一个驻留集大小,其中一部分是 V8 的堆内存。但由于后者显然保持在 ~150MB,因此它没有为我们提供有关前者增长的任何线索。 V8 的垃圾回收影响它的堆,而不是 RSS。很难猜测那里会发生什么,但是...

Since it's not causing me any real problems, can I gloss over?

...当然。让我们利用集体时间解决重要问题。

在v8内存图表中,Dynatrace不仅显示了堆内存,还将其与整个进程的驻留集大小进行了比较。有些人可能会觉得这令人困惑,但这极大地有助于将 JS 内存泄漏与本机内存泄漏区分开来。在您的情况下,似乎存在由本机模块引起的潜在本机内存泄漏。

您提到了 --max-memory-restart 参数,所以我猜您正在使用 Stack Overflow 上的 PM2. It's official documentation is not clear about whether the tool monitors just the memory used on the heap or overall memory usage. According to this article it seems that PM2 is not able to cover also native memory. Even more interesting are this bug report (closed but according to latest comments still not fixed) and the accepted answer to 问题。看来即使你的 PM2 版本也可能包含本机内存泄漏。

Here you can find more information on how to analyze a native memory leak in NodeJS. The accepted 上面提到的问题还列出了一些指向 PM2 替代品的链接。

顺便说一句,Dynatrace 会告诉您增加内存使用量是否会对您的服务/应用程序或最终用户体验产生任何可衡量的负面影响。