Node.js 堆内存不足

IT技术 javascript node.js crash out-of-memory heap-memory
2021-01-19 01:25:57

今天我运行了我的文件系统索引脚本来刷新 RAID 文件索引,4 小时后它崩溃并出现以下错误:

[md5:]  241613/241627 97.5%  
[md5:]  241614/241627 97.5%  
[md5:]  241625/241627 98.1%
Creating missing list... (79570 files missing)
Creating new files list... (241627 new files)

<--- Last few GCs --->

11629672 ms: Mark-sweep 1174.6 (1426.5) -> 1172.4 (1418.3) MB, 659.9 / 0 ms [allocation failure] [GC in old space requested].
11630371 ms: Mark-sweep 1172.4 (1418.3) -> 1172.4 (1411.3) MB, 698.9 / 0 ms [allocation failure] [GC in old space requested].
11631105 ms: Mark-sweep 1172.4 (1411.3) -> 1172.4 (1389.3) MB, 733.5 / 0 ms [last resort gc].
11631778 ms: Mark-sweep 1172.4 (1389.3) -> 1172.4 (1368.3) MB, 673.6 / 0 ms [last resort gc].


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x3d1d329c9e59 <JS Object>
1: SparseJoinWithSeparatorJS(aka SparseJoinWithSeparatorJS) [native array.js:~84] [pc=0x3629ef689ad0] (this=0x3d1d32904189 <undefined>,w=0x2b690ce91071 <JS Array[241627]>,L=241627,M=0x3d1d329b4a11 <JS Function ConvertToString (SharedFunctionInfo 0x3d1d3294ef79)>,N=0x7c953bf4d49 <String[4]\: ,\n  >)
2: Join(aka Join) [native array.js:143] [pc=0x3629ef616696] (this=0x3d1d32904189 <undefin...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [/usr/bin/node]
 2: 0xe2c5fc [/usr/bin/node]
 3: v8::Utils::ReportApiFailure(char const*, char const*) [/usr/bin/node]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/usr/bin/node]
 5: v8::internal::Factory::NewRawTwoByteString(int, v8::internal::PretenureFlag) [/usr/bin/node]
 6: v8::internal::Runtime_SparseJoinWithSeparator(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/bin/node]
 7: 0x3629ef50961b

服务器配备 16GB RAM 和 24GB SSD 交换。我非常怀疑我的脚本是否超过了 36GB 的内存。至少不应该

脚本使用文件元数据(修改日期、权限等,无大数据)创建存储为对象数组的文件索引

这是完整的脚本代码:http : //pastebin.com/mjaD76c3

过去我已经用这个脚本经历过奇怪的节点问题,例如什么迫使我。将索引拆分为多个文件,因为节点在处理诸如 String 之类的大文件时出现故障。有什么方法可以改善具有庞大数据集的 nodejs 内存管理?

6个回答

如果我没记错的话,如果不手动增加内存使用量,V8 中的内存使用量有一个严格的标准限制,大约为 1.7 GB。

在我们的一个产品中,我们在部署脚本中遵循了这个解决方案:

 node --max-old-space-size=4096 yourFile.js

还有一个新的空间命令,但正如我在这里读到的:a-tour-of-v8-garbage-collection新空间只收集新创建的短期数据,旧空间包含所有引用的数据结构,这些数据结构应该在你的情况是最好的选择。

我正在使用 angular 4 进行开发并遇到同样的问题,angular 应用程序的 yourFile.js 文件应该是什么?
2021-03-21 01:25:57
哪个文件放在 yourFile.js 中?Nodemon 文件或 NodeJS 文件?
2021-03-26 01:25:57
@VikramSingh 您是在使用ng serve还是ng build通过其他网络服务器(如 express)分发/dist 文件夹的结果但是,如果您的 Angular 项目使用的内存超过标准的 1.7GB 内存,那么您的应用程序可能会遇到架构问题?看起来您正在使用带有 nmp start 的开发环境,也许这是一个解决方案github.com/mgechev/angular-seed/issues/2063
2021-03-29 01:25:57
以同样的方式,此配置在框架上独立用于 nodejs。@Simer
2021-04-05 01:25:57
用于启动服务器的 index,js 文件 @Techdive
2021-04-05 01:25:57

如果你想全局增加节点的内存使用——不仅仅是单个脚本,你可以导出环境变量,像这样:
export NODE_OPTIONS=--max_old_space_size=4096

然后在运行像 npm run build.

即使设置NODE_OPTIONS为 4096 或更多,我也遇到相同的错误当我运行该命令时npm run build,我看到一些进程在使用诸如usr/bin/node --max_old_space_size=2048. 可能是什么原因?
2021-03-11 01:25:57
@AyeshWeerasinghe 可能您正在使用或运行的库或脚本具有max_old_space_size覆盖导出的 env 变量的硬编码参数。
2021-04-08 01:25:57
为方便起见,添加到 bash_profile 或 zsh 配置文件。
2021-04-09 01:25:57

以防万一有人在无法直接设置节点属性的环境中遇到这种情况(在我的情况下是构建工具):

NODE_OPTIONS="--max-old-space-size=4096" node ...

如果无法在命令行上传递节点选项,则可以使用环境变量设置节点选项。

@Keselme 环境变量是在服务器上设置的变量,所有进程都可以从中读取数据。打开一个 SSH 终端到您的服务器并输入:MY_VAR=hello 然后输入:echo $MY_VAR。您将看到它在终端中打印“hello”。您刚刚设置了一个环境变量并将其读回。
2021-03-27 01:25:57
当您说“...使用环境变量设置节点选项..”时,您能解释一下您的意思吗?
2021-03-30 01:25:57
在 Ubuntu 18.04 上工作,只是将导出命令添加到我的 bashrc 文件中
2021-03-31 01:25:57

这里有一些标志值,用于添加一些关于如何在启动节点服务器时允许更多内存的附加信息。

1GB - 8GB

#increase to 1gb
node --max-old-space-size=1024 index.js

#increase to 2gb
node --max-old-space-size=2048 index.js 

#increase to 3gb
node --max-old-space-size=3072 index.js

#increase to 4gb
node --max-old-space-size=4096 index.js

#increase to 5gb
node --max-old-space-size=5120 index.js

#increase to 6gb
node --max-old-space-size=6144 index.js

#increase to 7gb
node --max-old-space-size=7168 index.js

#increase to 8gb 
node --max-old-space-size=8192 index.js 

@HarryMoreno 您实际上可以输入您喜欢的任何数值。不必是 2 的幂。不过不确定比率。这只是一个最大限制,它不会使用所有内存。我会根据您的需要将其设置为高,然后根据需要缩小规模。
2021-03-11 01:25:57
我会试试系统内存 - 1GB。假设此 vm 仅用于运行此节点应用程序。
2021-03-14 01:25:57
@HarryMoreno 良好的系统内存与最大旧空间大小之比完全取决于您的机器上正在运行的其他内容。您可以将其增加为 2 的幂 - 或者您可以使用任何数字。您可以将其设置为大于系统内存 - 但您会遇到交换问题。
2021-03-29 01:25:57
可以继续以 2 的幂增加它吗?应该将其设置为大于系统内存吗?如果不是,什么是好的系统内存与最大旧空间大小的比率?
2021-04-04 01:25:57

我的 EC2 实例 t2.micro 遇到了同样的问题,它有 1 GB 内存。

我通过使用url创建交换文件并设置以下环境变量来解决该问题

export NODE_OPTIONS=--max_old_space_size=4096

终于问题解决了。

我希望这对未来有帮助。

感谢分享。我遇到了同样的问题,你的提示对我来说很好用。
2021-03-22 01:25:57
伟大的!在 Azure Standard_B1s 为我工作
2021-03-30 01:25:57
谢谢。在我创建了一个 2GB 交换文件并将“ENV NODE_OPTIONS=--max_old_space_size=1024”添加到我的 Dockerfile 之后,我现在可以在我的 $5/mo Linode nanode 实例上“纱线构建”Strapi。不确定在我的情况下是否需要交换步骤,但它不会受到伤害。
2021-04-04 01:25:57
确切地说,对于小型机器,您可能需要使其更而不是更大,例如 export NODE_OPTIONS=--max_old_space_size=1024
2021-04-07 01:25:57