Node.js堆内存不足

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

L猿2020/03/23 11:42:45

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

希望这可以解决问题。

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

猴子村村2020/03/23 11:42:45

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

node --expose-gc --max-old-space-size=8192 node_modules/react-scripts/scripts/build.js
斯丁前端2020/03/23 11:42:45

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

Tom凯2020/03/23 11:42:45

我已经尝试了以下代码及其正常工作。

  • 从项目根目录打开终端
  • 执行cmd设置新大小。

    set NODE_OPTIONS=--max_old_space_size=8172
    

或者您可以检查链接以获取更多信息 https://github.com/nodejs/node/issues/10137#issuecomment-487255987

Stafan2020/03/23 11:42:45

对于角度,项目捆绑,我已经添加了下面一行的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

希望这可以帮助!

Sam逆天2020/03/23 11:42:45

可以使用以下环境变量:

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

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

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

泡芙GO2020/03/23 11:42:45

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

Harry宝儿2020/03/23 11:42:45

接下来,用诸如memwatch之类的东西找到并修复存储猪可能会有所帮助。

蛋蛋猿2020/03/23 11:42:44

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

variable name = NODE_OPTIONS
variable value = --max-old-space-size=4096
西门2020/03/23 11:42:44

在进行AOT角度构建时,我遇到了类似的问题。遵循命令可以帮助我。

npm install -g increase-memory-limit
increase-memory-limit

资料来源:https : //geeklearning.io/angular-aot-webpack-memory-trick/

小卤蛋2020/03/23 11:42:44

解决此问题的步骤(在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" %*
)
小卤蛋2020/03/23 11:42:44

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

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

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

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

2020/03/23 11:42:44

我在尝试使用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"
        ]
    }
]}
小胖Gil2020/03/23 11:42:44

即使设置--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

Tom凯2020/03/23 11:42:44

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

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 

Itachi梅2020/03/23 11:42:44

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

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

Stafan2020/03/23 11:42:44

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

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

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