Node.js堆内存不足

544

今天我运行了我的文件系统索引脚本来刷新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

我以前已经遇到过这个脚本的一些奇怪的问题,例如,当处理像字符串这样大的文件时,节点会出现故障,因此我不得不将索引拆分成多个文件。有没有办法改善Node.js对大型数据集的内存管理?


6
对于Windows的命令提示符(cmd):set NODE_OPTIONS=--max-old-space-size=8192 的意思是设置Node.js进程的最大内存限制为8192 MB。 - shabarinath
有人能确认这个问题是否可能是由于 CPU 不足引起的吗?在我的情况下,我有 32GB 的 RAM,并为节点选项指定了约 11G,但只有 2 个CPU。仍然会出现 OOM。 - Rajesh Swarnkar
我在tsconfig.json的compilerOptions中添加了"memoryLimit": 4096。 这对我起了作用。 - undefined
34个回答

1

将Node升级到最新版本。我之前使用的是Node 6.6,出现了这个错误,然后升级到了8.9.4,问题就解决了。


1
如果给出的答案中有任何一个对你不起作用,请检查你安装的Node是否与你的系统兼容(即32位或64位)。通常,这种类型的错误是由于不兼容的Node和操作系统版本引起的,终端/系统不会告诉你这一点,但会持续给出内存不足的错误。

1
这对我起作用。我有不兼容的 Node 和 npm 版本。谢谢。 - Anna

1

我在Windows电脑上遇到了同样的问题,我注意到它在Git Bash中无法工作,但是在PowerShell中可以正常运行。


1
我今天遇到了同样的问题。对我来说,问题是我试图将大量数据导入到我的 NextJS 项目的数据库中。
所以我做的是,像这样安装 win-node-env 包:
yarn add win-node-env

由于我的开发机是 Windows 系统,所以我选择先本地安装,再全局安装。你也可以像这样全局安装:yarn global add win-node-env
然后,在我的 NextJS 项目的 package.json 文件中,我添加了另一个启动脚本,如下所示:
"dev_more_mem": "NODE_OPTIONS=\"--max_old_space_size=8192\" next dev"

这里,我传递了节点选项,即将8GB设置为限制。因此,我的package.json文件有点像这样:
{
  "name": "my_project_name_here",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "dev_more_mem": "NODE_OPTIONS=\"--max_old_space_size=8192\" next dev",
    "build": "next build",
    "lint": "next lint"
  },
  ......
}

然后我像这样运行它:
yarn dev_more_mem

对我来说,我只在我的开发机器上遇到了这个问题(因为我正在导入大量数据)。因此,这个解决方案。想分享一下,因为它可能对其他人有用。

1
"--max_old_space_size" 应该用连字符写成 "--max-old-space-size",对吗? - undefined
1
@Lionel 謝謝你指出那個錯字。我已經編輯了我的答案。加油! - undefined

1
对于Angular,我是这样解决的:
Package.json中,在script标签内添加以下内容。
"scripts": {
  "build-prod": "node --max_old_space_size=5048 ./node_modules/@angular/cli/bin/ng build --prod",
},

现在在终端/cmd中,不再使用ng build --prod,只需使用

npm run build-prod

如果您只想在build中使用此配置,请从所有3个位置中删除--prod

0

如果你想启动的不是node本身,而是其他软件,例如webpack,你可以使用环境变量和cross-env包:

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

0

如果有人在使用生成大量日志的nodejs应用程序时遇到此问题,可以尝试将标准输出流重定向到文件中,这可能会有所帮助。


0

所有这些单一的答案都对我没用(虽然我没有尝试更新npm)。

以下是有效的解决方法:我的程序使用了两个数组。一个是被JSON解析的,另一个是从第一个数组的数据生成的。在第二个循环之前,我只需要将第一个被JSON解析的数组设置回[]

这样就释放了大量的内存,使得程序可以继续执行,而不会在某些点上导致内存分配失败。

干杯!


0

以下是解决Node.js中“堆内存不足”错误的方法:

  1. 在启动应用程序时,使用--max-old-space-size标志来增加分配给Node.js进程的内存量。例如,您可以通过运行node --max-old-space-size=4096 index.js将限制增加到4GB。

  2. 使用内存泄漏检测工具,例如Node.js堆转储模块,来识别和修复应用程序中的内存泄漏。您还可以使用node inspector并使用chrome://inspect来检查内存使用情况。

  3. 优化您的代码以减少所需的内存量。这可能涉及减小数据结构的大小、重复使用对象而不是创建新对象或使用更有效的算法。

  4. 使用垃圾收集器(GC)算法自动管理内存。Node.js默认使用V8引擎的垃圾收集器,但您也可以使用其他GC算法,例如Node.js中的垃圾回收。

  5. 使用像Docker这样的容器化技术,限制容器可用的内存量。

  6. 使用像pm2这样的进程管理器,如果节点应用程序内存不足,则允许自动重新启动。


1
你在撰写这篇回答时是否使用了任何生成式人工智能? - undefined

0
对于 Angular 项目打包,我已经在我的 package.json 文件的 scripts 部分中添加了以下行。
"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

希望这可以帮到你!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接