首页 > 解决方案 > 常驻内存大于 --max-old-space-size 阈值?

问题描述

我正在我的服务器上运行一个 dockerised node.js 应用程序,使用--max-old-space-size限制应用程序堆大小的选项。以下输出由 htop 给出:

  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
10158 root       20   0  4284   720   644 S  0.0  0.0  0:00.00 sh -c node --max-old-space-size=512 ./dist/www.js
10159 root       20   0 1841M  929M 29592 S  0.0  3.0  1h31:16 node --max-old-space-size=512 ./dist/www.js
10160 root       20   0 1841M  929M 29592 S  0.0  3.0  0:00.00 node --max-old-space-size=512 ./dist/www.js
10161 root       20   0 1841M  929M 29592 S  0.0  3.0  7:27.13 node --max-old-space-size=512 ./dist/www.js
10162 root       20   0 1841M  929M 29592 S  0.0  3.0  7:26.96 node --max-old-space-size=512 ./dist/www.js
10163 root       20   0 1841M  929M 29592 S  0.0  3.0  7:26.99 node --max-old-space-size=512 ./dist/www.js
10164 root       20   0 1841M  929M 29592 S  0.0  3.0  7:26.64 node --max-old-space-size=512 ./dist/www.js

您可以看到我的应用程序常驻内存 (929M) 远高于我的max-old-space-size值 (512MB) 那么为什么会出现这种情况?此时应用程序不应该中止吗?

系统信息

Docker version: 19.03.5
node image version: 11.13.0

uname -v
#31~18.04.1-Ubuntu SMP Tue Nov 17 10:48:34 UTC 2020

标签: node.jsdockerubuntumemory-managementv8

解决方案


V8 开发人员在这里。该--max-old-space-size标志不直接控制整个进程的内存消耗;它限制了 V8 托管(即垃圾收集)堆的一部分(最大部分),这是放置所有 JavaScript 对象的内存块。除了这个“旧空间”,V8 还有一个(小得多的)“新空间”;而除了 V8 的托管堆之外,进程中还有很多其他的内存消费者:例如,在 V8 中,解析器和编译器使用托管堆之外的内存;然后除了 V8 之外,Node 还把一堆东西放在了内存中。根据嵌入器(即节点)和执行代码的具体作用,大字符串和 ArrayBuffers 也可以存在于托管堆之外。

简而言之,--max-old-space-size给你一个旋钮来影响将使用多少内存,但你设置的限制不是进程整体内存消耗的限制。(相比之下,在 Chrome 中,通常大约三分之一的渲染器进程的内存是 V8 的托管堆,尽管取决于网站所做的两个方向都有明显的异常值。我不知道 Node 的典型数字。)


推荐阅读