致命错误:调用和重试最后一次分配失败 - 进程内存不足

209

Node版本为v0.11.13

根据sudo top,崩溃期间的内存使用率不超过3%

导致此错误的代码:

var request = require('request')
var nodedump = require('nodedump')

request.get("http://pubapi.cryptsy.com/api.php?method=marketdatav2",function(err,res)
{
    var data
    console.log( "Data received." );
    data = JSON.parse(res.body)
    console.log( "Data parsed."   );
    data = nodedump.dump(data)
    console.log( "Data dumped."   ); 
    console.log( data )
})

为了检查是否存在递归栈大小问题,我运行了下面的代码,并带有 --stack-size=60000 参数。
var depth = 0;

(function recurse() {
    // log at every 500 calls
    (++depth % 500) || console.log(depth);
    recurse();
})();

并拥有

264500 
Segmentation fault

我运行了一段代码,使用相同的 --stack-size=60000 参数,但出现了 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory 错误,并且没有得到 Segmentation fault 错误提示。

因此,我得出结论,CALL_AND_RETRY_LAST 与递归栈大小无关。

我该如何解决这个问题?我相信我的计算机上有足够的可用内存来成功完成这个任务。

在 stackoverflow 上有类似的问题,但这些问题都不涉及 CALL_AND_RETRY_LAST,所以我创建了这个单独的问题。


3
您的代码在我使用 Node.js 0.10.28 版本时运行良好。它使用了 1200 MB 虚拟内存,并在屏幕上打印了大量信息,但似乎“可用”。 - John Zwinck
1
垃圾正是我想要的东西。不好的是,节点0.10.*不支持harmony生成器,因此我不能将其用于此目的。 - user619271
19个回答

127
如果您查看源代码:github/v8,似乎您正在尝试保留一个非常大的对象。据我的经验,如果您尝试解析一个巨大的JSON对象,就会发生这种情况,但是当我使用JSON和node0.11.13解析您的输出时,它可以正常工作。
您不需要更多的--stack-size,您需要更多的内存:--max_new_space_size和/或--max_old_space_size
除此之外,我可以给您的唯一提示是尝试另一个JSON解析器和/或尝试将输入格式更改为仅为JSON行。

12
非常感谢!我定义了--max_old_space_size=2000000,我相信这意味着约为2GB,解决了我的问题。变化的--max_new_space_size似乎根本没有任何效果。 - user619271
1
@theWanderer4865,您说的“尝试将输入格式更改为JSON行而不是仅限于JSON”是什么意思?您能详细说明一下吗?谢谢。 - titusmagnus
@titusmagnus 我没有回答这个问题,也许 OP 可以解释得更多。我猜他可能指的是换行分隔的 JSON,但我不确定100%。 - theWanderer4865
16
@user619271 --max_old_space_size=2048 表示分配 2GB 的内存空间。 - Timeless
1
哈哈.. @Timeless - technophyle
显示剩余5条评论

61
$ sudo npm i -g increase-memory-limit

在项目的根目录下运行:

$ increase-memory-limit

此工具将在node_modules/.bin/*文件中的所有node调用后面添加--max-old-space-size=4096参数。


Node.js版本>= 8 - 弃用通知

自从Node.js V8.0.0版本以后,可以使用选项--max-old-space-sizeNODE_OPTIONS=options...

$ export NODE_OPTIONS=--max_old_space_size=4096

你好,@sol-ibit。4096个参数是什么意思? - estebanpdl
1
嗨@estebanpdl, 增加Node.js应用程序内存的解决方案是使用额外的V8标志启动进程:--max-old-space-size。您需要附加所需的内存大小(以兆字节为单位)。以下命令将以4 GB的内存限制启动您的应用程序。 - sol404
2
使用export NODE_OPTIONS=--max_old_space_size=4096设置变量对我很有帮助!谢谢! - Tarator

47

为解决此问题,您需要使用选项--max_old_space_size增加内存限制并运行应用程序。默认情况下,Node.js的内存限制为512 MB。

node --max_old_space_size=2000  server.js 

6
请问是否有一份逐步指南可以告诉我如何操作呢? 我应该在哪里粘贴这段可信代码: node --max_old_space_size=2000 server.js - Mr. Benedict
@Mr.Benedict 当您启动应用程序时,请执行此操作。 - easymoden00b
2
node --max_old_space_size=2048 server.js 更合适...谢谢工作 - danday74
1
我在谷歌云上有一个React应用程序。我该怎么办?请问有人可以指导吗? - Shubham Kushwah
1
@easymoden00b,不是node server.js,而是npm start。我该怎么做? - Shubham Kushwah
显示剩余3条评论

33

注意:请查看评论中关于此操作如何影响Electron应用程序的警告。

从2017年8月发布的v8.0开始,NODE_OPTIONS环境变量公开了此配置(请参见NODE_OPTIONS已经登陆8.x!)。根据文章,只有源代码中列出的白名单选项(注意:链接不是最新的!)是允许使用的,其中包括"--max_old_space_size"。请注意,这篇文章的标题似乎有点误导人——NODE_OPTIONS似乎已经存在,但我不确定它是否公开了此选项。

因此,我在我的.bashrc文件中添加了以下内容:
export NODE_OPTIONS=--max_old_space_size=4096


1
警告:不要将此设置为Windows机器上的环境变量。它会破坏一切。它会破坏GitKraken,Slack,基于Chromium的VS2017安装程序,与Azure相关的VS2017扩展甚至是VS2017中的“扩展和更新”菜单项。 - Roman Starkov
1
请查看 https://github.com/electron/electron/issues/12695 - 看起来 Electron 在 2.0.3 中不会因 NODE_OPTIONS 而崩溃 - 但我只在特定的项目目录中使用 smartcd 设置 NODE_OPTIONS,以避免此问题 https://github.com/cxreg/smartcd - Ben Creasy
啊,这可能解释了为什么Discord和VS Code没有受影响。 - Roman Starkov
7
如何在Windows机器上实现这个? - Mahmoud Ezzat

31

我发现在node 4.1.1中,max_new_space_size选项不可用,并且仅使用max_old_space_size无法解决我的问题。 我在我的shebang中添加了以下内容,这些组合似乎有效:

#!/usr/bin/env node --max_old_space_size=4096 --optimize_for_size --max_executable_size=4096 --stack_size=4096

[编辑]: 4096等于4GB的内存,如果您的设备内存不足,您可能需要选择较小的数量。

[更新]: 在运行之前像这样运行grunt时还发现了此错误:

./node_modules/.bin/grunt

将命令更新为以下内容后,它停止出现内存错误:

node --max_old_space_size=2048 ./node_modules/.bin/grunt 

4
我添加了“--max_old_space_size=8192”参数,但这并没有解决问题,反而导致了电脑卡顿 :( - Dhyey
我已经根据反馈将示例中的内存从8GB降低到了4GB。谢谢。 - jfunk

23

现在已经废弃了increase-memory-limit模块。 自从Node.js v8.0于2017年8月发布以来,我们现在可以使用NODE_OPTIONS环境变量全局设置max_old_space_size

export NODE_OPTIONS=--max_old_space_size=4096

参考链接:https://github.com/endel/increase-memory-limit


你要在哪里设置?我正在使用 Azure DevOps 构建,并且在 Windows 代理上构建失败。 - int-i
1
为了避免跨平台差异,请全局安装 cross-env 模块,并在终端上运行以下命令 - cross-env PORT=8000 node --max-old-space-size=4096 server.js - SuperStar518
Azure DevOps 构建是在云上的 MS 代理上运行的,没有控制台来执行它们。我发现了另一种使用 PowerShell 实现这些的方法。我已将其添加为答案。 - int-i

13

以上答案只是一个变体。我尝试了上面的纯节点命令,但没有成功,但是来自这个Angular CLI问题的建议对我有用-您可以在package.json文件中创建一个Node脚本,以增加运行生产构建时可用的内存。

因此,如果您想将可用于Node的内存增加到4GB(max-old-space-size=4096),则您的Node命令将是node --max-old-space-size=4096 ./node_modules/@angular/cli/bin/ng build --prod。(根据您的需求增加或减少内存量-4GB适合我,但您可能需要更多或更少)。然后,您会像这样将其添加到您的package.json的“scripts”部分:

"prod": "node --max-old-space-size=4096 ./node_modules/@angular/cli/bin/ng build --prod"

它将与其他可用脚本一起包含在scripts对象中,例如:

"scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "prod": "node --max-old-space-size=4096./node_modules/@angular/cli/bin/ng build --prod"
}

通过调用 npm run prod 来运行它(如果您使用的是 Mac 或 Linux,则可能需要运行 sudo npm run prod )。

请注意,可能存在导致 Node 需要更多内存的潜在问题——如果是这种情况,这并不会解决问题,但至少可以为 Node 提供执行构建所需的内存。


10

你还应该检查一下是否错误地安装了 x86 版本的 Node,而非 x64 版本。我也遇到过这种情况,因为在我的 x64 机器上 nodejs.org 预先选中了 x86 版本。


4
我犯了同样的错误!谢谢。 - Pablo Chvx
3
被低估的评论。这个解决了我的问题。 - Dan Gayle
1
非常被低估的评论。我一直在想为什么在尝试设置max_old_space_size时,nodejs位于Program Files(x86)下。卸载了x86并安装了x64;解决了我的问题。 - Key007

10

我的解决方案如下:

  • 安装cross-env
    npm install --save-dev cross-envnpm install -g cross-env
  • 修改package.json文件,添加新的构建脚本
    例如:
    ... "build:prod:ios": "cross-env NODE_OPTIONS='--max-old-space-size=8192' ionic cordova build ios --prod --release" ...
  • 下次构建使用该命令。
    npm run build:prod:ios

  • 问题已解决。


6
在Windows机器上运行以下命令:

set NODE_OPTIONS=--max_old_space_size=4096

该命令用于设置Node.js的内存限制大小为4096MB。

获取 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory - fabpico

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