如何确定 node.js 的正确“最大旧空间大小”?

Posted

技术标签:

【中文标题】如何确定 node.js 的正确“最大旧空间大小”?【英文标题】:How do I determine the correct "max-old-space-size" for node.js? 【发布时间】:2018-07-01 09:45:12 【问题描述】:

我很难理解 Node.js 如何根据参数 max-old-space-size 进行操作。

例如,我正在运行两个 t2.small AWS 实例(2GB RAM)。

不知道为什么,但我确实设置了max-old-space-size=4096 (4GB)。在这种情况下节点会做什么?这种配置是否会导致内存分配失败?

如何根据服务器资源确定max-old-space-size的正确值?

我的应用程序的内存使用量不断增加,我正在尝试了解有关节点内部的一切。

【问题讨论】:

我现在正在添加一条评论,因为我看到我看到这越来越安静了。我花了整整一周的时间才意识到我的 NodeJS 应用程序没有内存泄漏,但垃圾收集器从未启动过。在 t2.micro 或 t2.small 实例等内存不足的系统上要注意这一点。由于 RAM 不可用,服务器将崩溃。 有没有办法让垃圾收集器启动? 配置的 max-old-space-size 的限制高于机器的 RAM 总量。 值得尝试--optimize-for-size 以减少内存使用量。 @ZG101 要让垃圾收集器运行,请参阅***.com/questions/27321997/… 【参考方案1】:

2020 年更新

这些选项是now documented officially by node。对于 2GB 的机器,您可能应该使用:

NODE_OPTIONS=--max-old-space-size=1536

确定用量

您可以使用free -m 查看 Linux 机器上的可用内存。请注意,您可以将freebuffers/cache 内存的总和视为可用内存,因为buffers/cache 可以在需要时立即丢弃(这些缓冲区和缓存是使用其他未使用内存的好方法)。

official documentation formax-old-space-size 还提到:

在具有 2GB 内存的机器上,考虑将其设置为 1536 (1.5GB)

因此上面的值。考虑到基本操作系统所需的内存量并没有太大变化,因此您可以在 4GB 机器上愉快地做 3.5 等。

注意默认值并查看更改的效果:

默认为 2GB:

$ node

> v8.getHeapStatistics()

  ....
  heap_size_limit: 2197815296,

2197815296 是 2GB 字节。

设置为8GB时,可以看到heap_size_limit的变化:

$ NODE_OPTIONS=--max_old_space_size=8192 node
Welcome to Node.js v14.17.4.
Type ".help" for more information.
> v8.getHeapStatistics()

  ...
  heap_size_limit: 8640266240,
  ...

正如@Venryx 在下面提到的,您也可以使用process.memoryUsage()

【讨论】:

从您从 Node.js 文档共享的链接中,它说:“在具有 2GB 内存的机器上,考虑将其设置为 1536 (1.5GB)” 谢谢@IdanDagan,我会将其添加到答案中。 吹毛求疵:这里没有理由更喜欢“整数”。 1535 或 1537 或 1500 或 1555 一样好。 确实如此 - 但由于内存以字节为单位,我们只选择了这些字节的四分之一(除了 NUMA/缓存一致性等性能概念)。 作为v8.getHeapStatistics()的替代品,您还可以使用:process.memoryUsage()(如seen here)【参考方案2】:

对我来说,当内存消耗接近 2GB 时,Azure 函数调用在 7GB 实例中终止,并显示以下错误消息。

Exception while executing function: Functions.graphql-mobile node exited with code 134
 [24164:000001CE2EB5CF00] 10557962 ms: Scavenge (reduce) 2041.0 (2050.5) -> 2040.1 (2051.5) MB, 2.3 / 0.1 ms  (average mu = 0.179, current mu = 0.002) allocation failure ,FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - javascript heap out of memory, 3: 00007FF73E006026 node::OnFatalError+294 

我通过在我的应用程序设置中像这样设置 max-old-space-size 解决了这个问题

"languageWorkers:node:arguments": "--max-old-space-size=5500"

【讨论】:

【参考方案3】:

当为正在执行的应用程序分配的内存小于所需内存时,会发生此错误。 默认情况下,Node.js 中的内存限制为 512 MB。要增加此数量,您需要设置内存限制参数—-max-old-space-size。这将有助于避免内存限制问题。

node --max-old-space-size=1024 index.js #increase to 1gb
node --max-old-space-size=2048 index.js #increase to 2gb
node --max-old-space-size=3072 index.js #increase to 3gb
node --max-old-space-size=4096 index.js #increase to 4gb
node --max-old-space-size=5120 index.js #increase to 5gb
node --max-old-space-size=6144 index.js #increase to 6gb
node --max-old-space-size=7168 index.js #increase to 7gb
node --max-old-space-size=8192 index.js #increase to 8gb

https://medium.com/@vuongtran/how-to-solve-process-out-of-memory-in-node-js-5f0de8f8464c

【讨论】:

它应该超过分配的 RAM 内存 很难找到佐证;我在 V8 或 Node.js 的文档中找不到任何明确的内容。另一个系统我将 v10、12 和 14 的默认值报告为 0。FWIW 我发现一些最近的博主将最大内存声明为 1.5Gb (tejom.github.io/general/nodejs/v8/debugging/2017/01/16/…),并且 v12 具有基于系统的动态最大值( idginsiderpro.com/article/3257673/…). node -e "console.log(`node heap limit = $require('v8').getHeapStatistics().heap_size_limit / (1024 * 1024) Mb`)" -> v12.18.0 和 v14.3.0 -> 2096Mb,v10.20.1 -> 1432Mb @JaySeeAre,感谢该命令显示heap_size_limit。对于普通的 UNIX shell,它需要以不同的方式引用:node -e 'console.log(`node heap limit = $require("v8").getHeapStatistics().heap_size_limit / (1024 * 1024) Mb`)' 我的项目中没有 index.js 文件,请大家帮帮我。【参考方案4】:

“旧空间”是 V8 托管(也称为垃圾收集)堆(即 JavaScript 对象所在的位置)中最大和最可配置的部分,--max-old-space-size 标志控制其最大大小。随着内存消耗接近极限,V8 将花费更多时间进行垃圾回收以释放未使用的内存。

如果堆内存消耗(即 GC 无法释放的活动对象)超过限制,V8 将使您的进程崩溃(因为缺乏替代方案),因此您不想将其设置得太低。当然,如果您将其设置得太高,那么 V8 允许的额外堆使用可能会导致您的整个系统内存不足(并且由于缺乏替代方案,要么交换或终止随机进程)。

总之,在具有 2GB 内存的机器上,我可能会将 --max-old-space-size 设置为大约 1.5GB,以留出一些内存用于其他用途并避免交换。

【讨论】:

这正是我希望得到的答案,描述了系统或节点内存不足的边缘情况。 @jmrk: 看来你是完全正确的,但是当我使用 2GB RAM 和 4GB 交换并将“--max-old-space-size”设置为 4GB 时,节点进程会消耗所有 RAM 内存和卡在1.9GB。问题在这里“为什么要避免使用交换??”(节点版本 8.11.1) 该标志应该覆盖其他任何东西。请仔细检查是否有错别字。 来自d8 --help: --max-old-space-size (max size of the old space (in Mbytes))

以上是关于如何确定 node.js 的正确“最大旧空间大小”?的主要内容,如果未能解决你的问题,请参考以下文章

Node.js:创建存储在变量中的xlsx文件,但不确定如何保存它

如何在 node.js 中设置默认时区?

Node.js - 如何检索对象/数组中元素的值

Node.js 中 process.nextTick 的正确用例是啥?

在 node.js 中计算 Content-length 标头的正确方法是啥

在 Node.js 中编写非阻塞函数的正确方法