节点--max_old_space_size无法工作

13

Node 版本:6.9.x

我的应用程序出现了 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 错误。

因此我尝试使用 max_old_space_size 标志更改内存分配。

在执行 server.js 时,我使用 --max_old_space_size=4096 参数。

然而,它仍然以与之前相同的错误崩溃。 我还注意到,在崩溃时抛出的错误中的数字。 看起来仍是默认分配的1.4GB。

这是我的错误消息:

<--- Last few GCs --->

   84567 ms: Mark-sweep 1375.1 (1401.9) -> 1374.7 (1402.9) MB, 88.7 / 0.4 ms (+ 0.8 ms in 3 steps since start of marking, biggest step 0.5 ms) [allocation failure] [GC in old space requested].
   84648 ms: Mark-sweep 1374.7 (1402.9) -> 1374.7 (1402.9) MB, 81.3 / 0.0 ms [allocation failure] [GC in old space requested].
   84734 ms: Mark-sweep 1374.7 (1402.9) -> 1374.3 (1401.9) MB, 86.0 / 0.0 ms [last resort gc].
   84825 ms: Mark-sweep 1374.3 (1401.9) -> 1374.0 (1400.9) MB, 90.9 / 0.0 ms [last resort gc].


<--- JS stacktrace --->

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

Security context: 0x1bf641bcfb39 <JS Object>
    1: slowToString [buffer.js:460] [pc=0x2f7049a5d3d5] (this=0x93e46a2d6b1 <an Uint8Array with map 0x13be78e068d9>,encoding=0x1bf641bdd309 <String[4]: utf8>,start=53,end=3522765)
    2: toString [buffer.js:~488] [pc=0x2f70499b77a6] (this=0x93e46a2d6b1 <an Uint8Array with map 0x13be78e068d9>)
    3: arguments adaptor frame: 3->0
    4: deserialize [/opt/myServer/node_modu...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [node]
 2: 0x10d2fbc [node]
 3: v8::Utils::ReportApiFailure(char const*, char const*) [node]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [node]
 5: v8::internal::Factory::NewRawOneByteString(int, v8::internal::PretenureFlag) [node]
 6: v8::internal::Factory::NewStringFromOneByte(v8::internal::Vector<unsigned char const>, v8::internal::PretenureFlag) [node]
 7: v8::internal::Factory::NewStringFromUtf8(v8::internal::Vector<char const>, v8::internal::PretenureFlag) [node]
 8: v8::String::NewFromUtf8(v8::Isolate*, char const*, v8::String::NewStringType, int) [node]
 9: node::StringBytes::Encode(v8::Isolate*, char const*, unsigned long, node::encoding) [node]
10: node::Buffer::Utf8Slice(v8::FunctionCallbackInfo<v8::Value> const&) [node]
11: v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&)) [node]
12: 0x9da914 [node]
13: 0x9daffe [node]
14: 0x2f7047a092a7
Aborted (core dumped)

在“最近几个GC”部分,提到的内存大小总是约为1404 MB。我做错了什么?

系统无法再分配更多的内存吗?

8个回答

20

确保在脚本文件名之前放置选项:

  • 正确node --max-old-space-size=10000 index.js
  • 不正确node index.js --max-old-space-size=10000

这个问题困扰了我一段时间。


1
总是那些愚蠢的错误让我们花费最多的时间。 - Utkarsh Dixit

11

如果您使用的是更新版本的NodeJs,您可能不需要这个选项,因为它应该会使用所有可用的RAM。但是仍有人会遇到2GB或类似的内存限制问题。

以下是解决方法:

您可以为单个脚本添加标志,但我发现它并不总是有效。通常我使用一些CI工具在Shell上运行命令,所以对我来说,在package.json脚本部分没有标志也可以。 还有两个选项。 所以共3个选项:

选项1:将标志设置为单个node脚本:

node --max-old-space-size=4076 /path/to/script.js

选项2:为单个shell设置环境变量:

NODE_OPTIONS="--max-old-space-size=4076"
node /path/to/script.js

选项3. 为此shell设置环境变量,以及由此shell生成的所有进程:
export NODE_OPTIONS="--max-old-space-size=4076"
node /path/to/script.js

选项#3在第一次没有成功时帮了我很多次 :)

1
是的,对我也有帮助。第三个解决方案也对我有用。 - codebuff
1
第三个对我完美地起作用了。 - Anurag pareek
我正在使用Windows 11,并需要选择第三个选项路线(64位Node 11.9.0)。 - cchapin
1
更多细节...我的 "npm run build" 命令使用 terser-webpack-plugin 1.2.3 对 webpack 4.29.6 进行执行。在 "chunk asset optimization TerserPlugin" 阶段(添加了大量新的 TypeScript 代码后)内存使用量飙升。可能是因为 webpack 在单独的 cmd shell 中运行,当运行脚本或设置调用 cmd 环境中传递的 max-old-space-size 时没有被拾取到。 - cchapin
@cchapin,我认为你是对的,为什么只有#3起作用。Webpack可能会生成多个子进程,其中一个可能会耗尽内存,而且Webpack本身可能没有使用那么多,但这些子进程却使用了很多。虽然这只是猜测,如果有人知道确切的原因,请分享一下。 - Lukas Liesis
选项3在我的Mac上有效。谢谢! - obotezat

6

现在这个标记已经没有用了:

Node的版本>=12的应该不需要使用--optimize_for_size和--max_old_space_size标志,因为JavaScript堆限制将基于可用内存。


请问您能否提供源链接? - kvetis
1
当然,https://devcenter.heroku.com/articles/node-memory-use#tuning-the-garbage-collector - Jan aka uptech
2
这并不准确,他们增加了默认的最大大小,但还不足以运行需要4GB+内存的TypeScript或其他内存占用较大的程序。 - Dobes Vandermeer

3

请确保您使用的是64位的NodeJS。我曾经遇到类似的问题,最终发现我的问题与NodeJS本身有关。32位版本的NodeJS只能提供最多2GB的空间。


你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community
1
你觉得这不清楚吗? - Amin
谢谢!你帮我省了很多时间。团队中的一个开发人员遇到了内存错误,他安装了32位版本。安装64位版本后一切正常运行! - Florian Bezagu
@FlorianBezagu,我很高兴能够帮助到别人。 - Amin

2

设置 export NODE_OPTIONS="--max-old-space-size=16384" 在运行npm命令之前会起作用


0

尝试使用--max-old-space-size=4096,如果不起作用,请查看您是否有可用的内存来分配4GB。


你是指 --max_old_space_size 吗?因为看问题描述,我已经这样做了。我也尝试过 2048,而且我肯定有足够的空闲内存。 - Dushyant Bangal
好的,我以为那是个打字错误。我会尝试一下并回复你。 - Dushyant Bangal
3
破折号和下划线都可以使用。 - user993683
1
有时候由于某些原因它就不起作用了 https://github.com/nodejs/node/issues/2738#issuecomment-294354111 - Kalana Demel

0
如果您正在使用Express Generator,则需要在package.json中更新脚本。
scripts": {

   "start" :"node --max-old-space-size=4076 ./bin/www"

 }

-2

在我的情况下,解决方案与HTML有关。 我正在使用Vue 2,在我的HTML模板上,我在if语句中使用了动态数据:

<div>
  {{variableOne
    ?variableOne
    :variableTwo}}
  </div> 

所以我的错误是似乎在括号内不能写多行的if语句,所以我将代码写成了一行来修复它。
<div>
  {{variableOne?variableOne:variableTwo}}
  </div> 

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