我在理解Node.js如何基于max-old-space-size参数的行为时遇到了一些麻烦。

以我的例子为例,我运行2t2。小型AWS实例(2GB RAM)。

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

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

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


当前回答

对我来说,当内存消耗接近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"

其他回答

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

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

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

当分配给正在执行的应用程序的内存小于所需的内存时,就会发生此错误。 默认情况下,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

2020年更新

这些选项现在按节点正式记录。对于2GB的机器,您可能应该使用:

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

以确定用量

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

官方文件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()

对我来说,当内存消耗接近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"