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


99

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

以我的情况为例,我正在运行两个t2.smallAWS实例(2GB RAM)。

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

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

我的应用程序在不断增加内存使用量,我试图了解有关节点内部的所有内容。


8
现在我要添加一条评论,因为我看到它使视图安静了很多。我花了整整一个星期的时间才意识到我的NodeJS应用程序没有内存泄漏,但是垃圾收集器从未启动过。请注意在内存较低的系统(例如t2.micro或t2.small实例)上。由于RAM不可用,服务器将崩溃。
Borjante

有没有办法让垃圾收集器启动?
ZG101 '19

@Borjante为什么垃圾收集器没有运行?
神的

2
配置的max-old-space-size的限制比计算机具有的RAM总量高。
Borjante

值得尝试--optimize-for-size减少内存使用。
Constantinos

Answers:


135

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

如果堆内存消耗(例如,GC无法释放的活动对象)超过了限制,则V8将使您的进程崩溃(由于缺少替代项),因此您不想将其设置得太低。当然,如果将它设置得太高,则V8允许的额外堆使用量可能会导致整个系统内存不足(并且由于缺乏替代性,所以交换或杀死随机进程)。

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


6
这正是我希望得到的答案,它描述了系统或节点内存不足的极端情况。
Borjante

2
@jmrk:看来您是完全正确的,但是当我使用2GB RAM和4GB交换并将“ --max-old-space-size”设置为4GB时,节点进程将消耗所有RAM内存并停留在1.9GB上。问题在这里“为什么要避免使用交换?”(节点版本8.11.1)
Manish Trivedi,

1
该标志应覆盖其他任何内容。请仔细检查拼写错误。
jmrk

2
来自d8 --help--max-old-space-size (max size of the old space (in Mbytes))
jmrk

21

2020更新

这些选项现在已由node正式记录。对于2GB的计算机,您可能应该使用:

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

确定使用量:您可以使用来查看Linux计算机上的可用内存free -m。请注意,您可以结合使用free和和buffers/cache内存,因为它们buffers/cache可能会被丢弃(这些缓冲区和缓存是使用否则未使用的内存的不错方法)。

请注意官方文档max-old-space-size还提到:

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

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


2
从Node.js文档共享的链接中说:“在具有2GB内存的计算机上,考虑将其设置为1536(1.5GB)”
Idan Dagan

1
谢谢@IdanDagan,我将其添加到答案中。
mikemaccana

11

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

我不确定这是否成立。当然,在一个系统上我可以访问正在运行的节点10.20.1,我可以看到(带有node --v8-options)默认报告为4096,而没有设置max-old-space-size我正在运行的测试套件,则可以毫无问题地分配到1.5Gb。链接的中篇文章来自2016年,因此自撰写以来,事情可能会继续发展。
JaySeeAre

1
很难找到佐证。我在V8或Node的文档中找不到任何明确的内容。我报告的另一个系统将v10、12和14的默认值设置为0。FWIW我发现了一些较新的博客,他们将最大内存声明为1.5Gb(tejom.github.io/general/nodejs/v8/debugging/2017/ 01/16 /…),并且v12具有基于系统的动态最大值(idginsiderpro.com/article/3257673/…)。
JaySeeAre

4
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 '20

2
@JaySeeAre,感谢您的命令显示heap_size_limit。对于普通的UNIX shell,需要用不同的引号引起来:node -e 'console.log(`node heap limit = ${require("v8").getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`)'
Sam Watkins,

-9

如果只想使其从正在处理的项目中运行,请执行以下两个步骤:

  1. 在项目中cd到node_module / @ angular cd node_module / @ angular

  2. 现在运行以下命令export NODE_OPTIONS =-max-old-space-size = 8192


18
为什么需要转到@angular目录设置环境变量?
mgamsjager
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.