严重错误:在堆限制附近无效的标记压缩导致分配失败 - Ionic 3中的JavaScript堆内存不足

563

当我使用ionic serve命令运行Ionic 3项目时,我遇到了这个错误:

JavaScript致命错误:在堆限制附近无效的标记-压缩分配失败


请查看此答案:https://dev59.com/zlkT5IYBdhLWcg3wefQn#66914674 - sidverma
46个回答

658
对于那些通过谷歌搜索到这个问题的非Angular通用答案:
大多数情况下,当你遇到这个错误时,可能是因为内存泄漏、库的添加/升级或者Node.js在不同版本之间管理内存的差异(例如,Node.js版本<=10和Node.js版本>10)。
通常,只需增加分配给Node.js的内存即可使程序运行,但可能并不能真正解决实际问题,并且节点进程使用的内存仍然可能超过您分配的新内存。我建议在Node.js进程开始运行时对内存使用进行分析,或者升级到Node.js > 10。
我曾经有一个内存泄漏问题。 这里有一篇关于在Node.js中调试内存泄漏的优秀文章
话虽如此,要增加内存,在运行Node.js进程的终端中:
export NODE_OPTIONS="--max-old-space-size=8192"

或者适用于Windows系统:
Set NODE_OPTIONS="--max-old-space-size=8192"

其中max-old-space-size的取值可以是:[2048, 4096, 8192, 16384]等等。

更多示例以进一步明确:

export NODE_OPTIONS="--max-old-space-size=5120" # Increase to 5 GB
export NODE_OPTIONS="--max-old-space-size=6144" # Increase to 6 GB
export NODE_OPTIONS="--max-old-space-size=7168" # Increase to 7 GB
export NODE_OPTIONS="--max-old-space-size=8192" # Increase to 8 GB

# and so on...

# formula:
export NODE_OPTIONS="--max-old-space-size=(X * 1024)" # Increase to X GB

# Note: it doesn't have to be multiples of 1024.
# max-old-space-size can be any number of memory megabytes (MB) you have available.

查看 max-old-space-size(以 MB 为单位)的当前值

要查看 max-old-space-size(以 MB 为单位)的当前值(不是精确值,但非常接近),请在终端中运行

node -e 'console.log(v8.getHeapStatistics().heap_size_limit/(1024*1024))'

65
默认值为512 MB。您不必立刻跳到10倍的数量,您可以先尝试512到5120之间的某个值。 - Cameron Hudson
2
谢谢,这个适用于所有存在内存问题的应用程序。 - invinciblemuffi
45
只是想指出 - 这并不总是内存泄漏的表现。也许你正在使用的某个库比以前占用了更多的内存。对于我们来说,next.js 的快速刷新功能导致应用程序崩溃。 - Daniel Cooke
2
这里是文档 https://nodejs.org/api/cli.html#cli_max_old_space_size_size_in_megabytes,没有任何迹象表明应该有“整数*1024”的步骤。 - Mikhail Vasin
3
@MikhailVasin 请看我回答中的最后一条评论。我知道它不是这样的。我只是为那些想要以GB为单位的常见内存增量的人提供了这个选项。 - Emmanuel N K
显示剩余7条评论

103
在我的情况下,通过安装Node.js版本12.10.0来解决这个问题。

1
一样的情况。我刚刚改了版本,它就可以工作了。 - brunocascio
27
为了提供背景,Node 12采用一种基于可用内存而非默认值的堆管理策略。更多细节请参阅:https://foundation.nodejs.org/announcements/2019/04/24/node-js-foundation-and-js-foundation-merge-to-form-openjs-foundation-2 - Derek Dowling
1
@NitishKumar 我在使用Node 12时仍然遇到错误 /耸肩。 接受的答案应该是最能解决OP用例的答案 - 尽管你希望他们此时已经选择了其中一个答案。 - ruffin
2
@DerekDowling Wayback的链接失效了:https://web.archive.org/web/20191103115941/https://foundation.nodejs.org/announcements/2019/04/24/node-js-foundation-and-js-foundation-merge-to-form-openjs-foundation-2 - Grim
我正在使用 Node 12.18.3,出现了这个错误。 - RyanNerd
显示剩余5条评论

91

只需在终端中输入以下命令:

export NODE_OPTIONS="--max-old-space-size=8192"

当您超出Node.js默认允许的最大内存限制时,就会出现此错误。这只是增加了允许使用的最大内存。


3
如果你正在命令行界面工作,这是解决方案。 - Kareem Khaleel
@Matt,你能否在你的解决方案中添加一下,在我们实际调整之前如何查看“--max-old-space-size”的现有值? - klewis
1
这应该被接受为正确答案。谢谢分享。 - undefined

88

我在CentOS 7服务器上也遇到了同样的问题,但是下面的方法解决了我的问题:

node --max-old-space-size=X node_modules/@angular/cli/bin/ng build --prod

其中X = (2048或4096或8192等)表示内存的值。


3
修改 x 的值后,错误仍然保持不变。 - Sohail Ahmad
1
如果错误持续发生,请继续增加大小,直到有足够的内存来处理,最终将防止错误发生。我唯一遇到无法解决这个错误的情况是ng serve和在angular.jsonscripts部分引用了一个非常大的.js文件需要加载到内存中。 - atconway
我可以将X的值设置为大于8192吗?我有32GB的RAM。 - Diego
对我来说,在命令行中提供max-old-space-size并没有起作用。这可能与基于nvm的node有交互作用?相反,在bash脚本中,我使用了“NODE_OPTIONS = --max-old-space-size=2048 node $NG build --prod --progress=false”,它可以工作,而“node --max-old-space-size=2048 $NG build --prod --progress=false”则不行。我仍然不知道原因。 - Simon H
如果您在 Docker 中运行此程序并出现“KILLED”错误,请增加分配给 Docker 引擎的 RAM。 - Nima Ajdari

62

当我在Visual Studio Code中执行ng build命令时,我遇到了相同的错误。但是当我按照以下顺序在Windows命令行上执行同样的操作时,我可以成功构建。

步骤1.

set NODE_OPTIONS=--max_old_space_size=4096

第二步。

ng build

谢谢,这帮了我很多,我刚刚换了我的终端。 - Gayatri Dipali
我已将其添加到文件路径/Users/MY_USER/.nvm/versions/node/v10.13.0/lib/node_modules/npm/bin/npm.cmd中,它可以正常工作。 - Ahmed Wahba
这在GIT Bash上对我有效。 - Syed Uzair Uddin

42

Windows

从控制面板进入 系统高级系统设置环境变量新建 (用户或系统)

mceclip0.png

或者可以通过 PowerShell 来完成:

$env:NODE_OPTIONS="--max-old-space-size=8192"

如果有必要,您还可以增加这个数字。我们发现一些较大的项目需要将其增加到14GB!

Linux/macOS

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

我有NodeJS 10.15.3版本,在Windows 10上尝试了NODE-OPTIONS解决方案,但它没有起作用。还有其他的解决方案吗? - VenomBerry
@VenomBerry 你能运行WSL吗?为什么要在标准 Windows 上运行这些软件而不安装Linux子系统呢,这样会有很多麻烦。 - Evert
1
现在看起来我们必须在系统设置中使用max-old-space-size=8192而不带前导破折号。在Node.js中,使用--会导致“Fatal javascript OOM in GC during deserialization”错误。但可能只与最新版本有关。 - it3xl
1
针对较新的 Node 版本,您仍需要使用“--”参数,否则它将无法被视为更改。您遇到的问题是,(至少某些)新版本的 Node 实际上会向您要求的数字添加 24 字节,因此请求 4096MB 将变成 4294967320 字节或 4096.00002MB,而 Node 无法反序列化... 建议尝试 4000。 - mrVandal
我必须尝试使用下划线,因为连字符在“变量值”中无法正常工作。 --max_old_space_size=8192 - undefined
显示剩余2条评论

41
尝试这个解决方案,它在论坛的一条旧消息中被指出:3.7.0: iOS build with --prod not working

打开node_modules/@ionic/app-scripts/bin/ionic-app-scripts.js

将第一行改为:

#!/usr/bin/env node

to

#!/usr/bin/env node --max-old-space-size=4096

尝试使用1024和2048的值,但对于相对较大的应用程序,您可能需要使用4096。


你不应该更改 node_modules 内部的脚本。 - Faizi
这是一个补丁,临时解决方案。 - Braian Mellor

21
在我的情况下,是一个递归导致 React 使用了所有内存。这是在我重构代码时发生的,当时我没有注意到这一点。
const SumComponent = () => {
  return (
    <>
      <SumComponent />
    </>
  )
}

在其他 Node.js 应用程序中,这可能看起来像:

const someFunction = () => {
  ...
  someFunction();
  ...
}

2
为什么这是一个问题?使用<></>在React中应该有效,而不是使用<React.Fragment>,对吗? - Joelgullander
@Codehiker 是的,这是 React 16 中的新语法。 - Rusty
11
递归是指SumComponent包含一个SumComponent(该SumComponent又包含一个SumComponent,该SumComponent又包含一个SumComponent...) - stone

16

当我在Visual Studio Code中执行以下语句时,我遇到了同样的错误信息。但是当我在Windows命令行上执行同样的操作时,可以成功构建。

npm install -g increase-memory-limit
increase-memory-limit
set NODE_OPTIONS=--max_old_space_size=4096
ng build -c deploy --build-optimizer --aot --prod --sourceMap

1
在我的npm脚本或作为node_options直接设置--max_old_space_size=4096并没有起作用,但在安装了你指定的内容后开始起作用了。谢谢!!! - Caner

15

我将从Node.js 12升级到Node.js 14,这解决了我的问题。


更新
现在Node.js 16已经发布,我建议升级到最新的可用版本。


是的,我使用带有Angular 11的16.4.2版本解决了这个问题。 - DoubleA

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