Node.js堆内存不足


245

今天,我运行了用于文件系统索引编制的脚本,以刷新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的内存管理?

Answers:


313

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

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

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

还将有一个新的空间命令,但正如我在这里阅读的那样:a-tour-of-v8-garbage-collection新空间仅收集新创建的短期数据,而旧空间包含应在其中的所有引用数据结构您的情况最好的选择。


以同样的方式,该配置独立于框架上的nodejs。@ Simer
Felix,Felix,

我正在使用angular 4进行开发并遇到相同的问题,angular app的yourFile.js文件应该是什么?
维克拉姆

您正在使用@VikramSingh ng serve还是ng build由其他网络服务器(如express)分发/ dist文件夹的结果?但是,如果您的Angular项目使用的内存超过了标准的1.7GB,那么您的应用程序可能会遇到体系结构问题?看来您正在使用带有nmp start的开发环境,也许这是针对它的解决方案github.com/mgechev/angular-seed/issues/2063
Felix

我正在使用带有角度cli和aot(dist文件夹)的ng build
Vikram

2
index,js文件@Techdive,用于启动服务器
Basit

77

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

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

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


当您说“ ...使用环境变量设置节点选项。”时,能否解释您的意思?
Keselme,

6
@Keselme环境变量是在服务器上设置的变量,所有进程均可从中读取数据。打开服务器的SSH终端,然后键入:MY_VAR = hello,然后键入:echo $ MY_VAR。您会看到它在终端上显示“ hello”。您只需设置一个环境变量,然后将其读回即可。
罗布·埃文斯

在Ubuntu 18.04上工作,只是将导出命令添加到我的bashrc文件中
Rahal Kanishka,

74

如果要全局增加节点的内存使用量-不仅是单个脚本,还可以导出环境变量,如下所示:
export NODE_OPTIONS=--max_old_space_size=4096

然后,当运行类似的构建时,您无需使用文件 npm run build


24

我在尝试使用VSCode进行调试时遇到了此问题,因此只想添加此内容即可将参数添加到调试设置中。

您可以在中将其添加到runtimeArgs配置的属性中launch.json

请参见下面的示例。

{
"version": "0.2.0",
"configurations": [{
        "type": "node",
        "request": "launch",
        "name": "Launch Program",
        "program": "${workspaceRoot}\\server.js"
    },
    {
        "type": "node",
        "request": "launch",
        "name": "Launch Training Script",
        "program": "${workspaceRoot}\\training-script.js",
        "runtimeArgs": [
            "--max-old-space-size=4096"
        ]
    }
]}

21

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

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 

能否以2的幂次增加它?应该设置为大于系统内存吗?如果不是,那么最佳的系统内存与最大旧空间大小之比是多少?
哈里·莫雷诺

3
@HarryMoreno您实际上可以输入您喜欢的任何数字值。不必使用2的幂。这只是一个最大限制,不会使用所有内存。我会根据需要将其设置为高,然后根据需要缩小。
尼古拉斯·波特

我将尝试系统ram-1GB。假设此虚拟机仅用于运行此节点应用程序。
哈里·莫雷诺

2
@HarryMoreno一个好的系统内存与最大旧空间大小之比,完全取决于计算机上正在运行的其他内容。您可以将其增加2的幂-或者可以使用任何数字。您可以将其设置为大于系统内存-但会遇到交换问题。
Gigimoi

20

即使设置--max-old-space-size后,我仍然在为此付出努力。

然后我意识到需要在业力脚本之前放置选项--max-old-space-size。

也最好同时指定语法--max-old-space-size和--max_old_space_size我的karma脚本:

node --max-old-space-size=8192 --optimize-for-size --max-executable-size=8192  --max_old_space_size=8192 --optimize_for_size --max_executable_size=8192 node_modules/karma/bin/karma start --single-run --max_new_space_size=8192   --prod --aot

参考https://github.com/angular/angular-cli/issues/1652


5
最好同时指定两种语法--max-old-space-size和--max_old_space_size ”-您不需要这样做,它们是同义词。来自nodejs.org/api/cli.html#cli_options:“所有选项,包括V8选项,都允许用短划线(-)或下划线(_)分隔单词。”
ZachB

6
max-executable-size已删除,使用时以错误结尾:github.com/nodejs/node/issues/13341
crashbus

我不得不将其剪切--max-old-space-size=8192 --optimize-for-size --max_old_space_size=8192 --optimize_for_size并奏效
Sergey Pleshakov



10

解决此问题的步骤(在Windows中)-

  1. 打开命令提示符,%appdata%然后按回车键
  2. 导航到%appdata%> npm文件夹
  3. ng.cmd在您喜欢的编辑器中打开或编辑
  4. 添加--max_old_space_size=8192到IF和ELSE块

node.cmd更改后,您的文件如下所示:

@IF EXIST "%~dp0\node.exe" (
  "%~dp0\node.exe" "--max_old_space_size=8192" "%~dp0\node_modules\@angular\cli\bin\ng" %*
) ELSE (
  @SETLOCAL
  @SET PATHEXT=%PATHEXT:;.JS;=;%
  node "--max_old_space_size=8192" "%~dp0\node_modules\@angular\cli\bin\ng" %*
)

这是特定于Windows的。OP没有提及Windows。
丹·达斯卡斯库

@DanDascalescu更新了答案。感谢您通知
Umang Patwa

6

可以使用以下环境变量:

NODE_OPTIONS= --max-old-space-size=8192 .

另一个注意事项:console.log()还会占用终端中的内存。

只是尝试在终端上注释console.log()。因为那也会占用内存。


6
这是答案还是对某些答案的评论?有很多答案NODE_OPTIONS= --max-old-space-size=somesize
barbsan

5

如果要全局更改节点(Windows)的内存,请转至高级系统设置->环境变量->新用户变量

variable name = NODE_OPTIONS
variable value = --max-old-space-size=4096


4

我只想在某些系统中添加它,甚至使用来增加节点内存限制--max-old-space-size,这还不够,并且存在如下操作系统错误:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted (core dumped)

在这种情况下,可能是因为您达到了每个进程的最大mmap。

您可以通过运行来检查max_map_count

sysctl vm.max_map_count

并通过运行来增加它

sysctl -w vm.max_map_count=655300

并通过添加此行来修复重启后不将其重置

vm.max_map_count=655300

/etc/sysctl.conf文件中。

点击这里获取更多信息。

一种分析错误的好方法是通过运行 strace

strace node --max-old-space-size=128000 my_memory_consuming_process.js

3

我最近遇到了同样的问题,遇到了这个线程,但是我的问题是ReactApp。下面的节点启动命令更改解决了我的问题。

句法

node --max-old-space-size=<size> path-to/fileName.js

node --max-old-space-size=16000 scripts/build.js

为什么最大旧空间大小为16000?

基本上,它取决于该线程分配的内存和您的节点设置。

如何验证并给出正确的尺寸?

这基本上是我们的引擎v8。以下代码可帮助您了解本地节点v8引擎的堆大小。

const v8 = require('v8');
const totalHeapSize = v8.getHeapStatistics().total_available_size;
const totalHeapSizeGb = (totalHeapSize / 1024 / 1024 / 1024).toFixed(2);
console.log('totalHeapSizeGb: ', totalHeapSizeGb);

2

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

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

export NODE_OPTIONS=--max_old_space_size=4096

终于问题解决了。

我希望这对将来会有所帮助。


1

以防万一它可以帮助人们在使用产生大量日志的nodejs应用程序时遇到此问题,一位同事通过将标准输出传输到文件中来解决了此问题。


1

例如,如果您尝试不启动node本身,而是启动其他一些软件,则webpack可以使用环境变量和cross-env包:

$ cross-env NODE_OPTIONS='--max-old-space-size=4096' \
  webpack --progress --config build/webpack.config.dev.js

1

对于角度,项目捆绑,我已经添加了下面一行的pakage.json在文件脚本部分。

"build-prod": "node --max_old_space_size=5120 ./node_modules/@angular/cli/bin/ng build --prod --base-href /"

现在,为了捆绑我的代码,我使用npm run build-prod而不是ng build --requiredFlagsHere

希望这可以帮助!


0

将节点升级到最新版本。我在节点6.6上遇到此错误,并升级到8.9.4,问题消失了。


0

就我而言,我使用的是npm install先前版本的node,而一天后,我npm install为几个模块升级了node版本和ram 。在此之后,我得到了这个错误。为了解决这个问题,我从每个项目中删除了node_module文件夹,然后npm install再次运行。

希望这可以解决问题。

注意:这是在我的本地计算机上发生的,并且仅在本地计算机上已修复。


0

此命令可以完美运行。我的笔记本电脑中有8GB内存,因此我将大小设置为8192。都是关于ram的,而且您还需要设置文件名。我运行npm run build命令,这就是为什么我使用build.js的原因。

node --expose-gc --max-old-space-size=8192 node_modules/react-scripts/scripts/build.js

0

就我而言,我将node.js版本升级到了最新版本,它的工作就像一个魅力。


您好安吉拉,欢迎您来!您能否为以后的读者指定更新到的Node.js的确切版本?谢谢!
kant312

我升级到最新的LTS版本:12.18.0
Angela Rana
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.