编码代理与终端 · 收录于 2026-08-29 · 适用 2 工具 ✓ 实测验证

Node 构建/打包报 FATAL ERROR ... JavaScript heap out of memory(内存溢出)

已验证 2026-08-29Node 构建报 heap out of memory——NODE_OPTIONS=--max-old-space-size=8192 临时提上限(按机器内存定)。

快速修复

# 一键:临时提上限(值按机器内存定,如 4096/8192)
NODE_OPTIONS=--max-old-space-size=8192 npm run build

你会遇到什么

前端项目打包/构建(webpack、vite、vue-tsc、jest 等)中途崩溃,控制台最后几行是 FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory。

项目越大越容易触发(依赖多/单文件大/tsc 全量类型检查);重试可能偶发通过;发生在 npm run build / vue-tsc / CI 打包阶段。

本文路径:快速修复(30 秒一段命令)→ 一步步排查(可跳读)→ 原理与变体(症状/原因/证据)。赶时间直接跳到「快速修复」。

为什么会这样

Node 的 V8 引擎给 JS 堆设了默认上限,超过后 GC 也回收不动就放弃治疗直接崩。默认上限不是固定的 2G:现代 Node(64 位)默认约 4GB(本机 Node 22 实测 heap_size_limit = 4144MB),老版本或 32 位下更小(1.5~2G)——网上大量教程说的「默认 2G」是旧版本事实。构建工具要把整个依赖图 + 编译产物放内存,项目一大就顶到上限。

V8 给 JS 堆设「默认上限」的动机是:堆太大时 GC 停顿(mark-sweep)会让主线程长时间卡死,宁可先 OOM 也不无限增长。上限由架构与版本决定,不是固定 2G:64 位现代 Node 默认约 4GB(Node 22 实测 heap_size_limit=4144MB),老版本/32 位更小——「默认 2G」是旧版本的事实。构建工具把整个依赖图+编译产物放内存,项目一大就顶到上限。

确定性推论:OOM 先看 heap_size_limit 实际值(node -e "console.log(require('v8').getHeapStatistics.heap_size_limit)"),别信网上旧数字;

两条正路——--max-old-space-size 调大上限(构建脚本 NODE_OPTIONS=--max-old-space-size=8192,但要匹配机器内存)或减少峰值占用(分批处理、流式);

CI 里 OOM 常见原因是容器内存限制比默认上限还小——先看容器限额;判断路径:报错 heap out of memory + 构建类任务 = 上限问题,FATAL ERROR 段会打印当时限制。

一步步来

1. 临时提上限(最快) — 必做

三种写法等效:

node --max-old-space-size=8192 ./node_modules/vite/bin/vite.js build

或环境变量(CI/Jenkins/Windows 通用):NODE_OPTIONS=--max-old-space-size=8192;或写进 package.json:

"build": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build"

Windows 下注意引号问题可用 cross-env。值别超过物理内存太多,否则变 swap 卡死。

2. 长期优化(治本) — 必做

构建缓存(webpack cache / vite 缓存)、代码分割/按需加载、升级构建工具(webpack→vite)、vue-tsc --noEmit 拆到单独阶段、依赖精简。内存压力来自"同时放内存的东西太多",提上限只是把线抬高。

3. 区分系统 OOM — 必做

若错误是 Killed 或 Exit status 137(容器/CI 里),那是操作系统杀的(cgroup/容器内存上限),调 --max-old-space-size 没用,要加容器内存或减并发。

怎么确认修好了

提上限后构建通过(实测输出形态):

node --max-old-space-size=8192 <脚本> → 分配至 6000MB 上限成功退出(exit 0)
NODE_OPTIONS=--max-old-space-size=8192 node <脚本> → 同样成功(exit 0,环境变量与 CLI 等效)

默认上限运行 → 复现 FATAL ERROR + SIGABRT 退出码 134(实测)。

其它环境的表现

环境说明
默认上限现代 Node 约 4GB(实测 4144MB),旧版本/32 位更小
命令行node --max-old-space-size=8192 ...
环境变量NODE_OPTIONS=--max-old-space-size=8192(CI/Windows 通用)
package.jsoncross-env 写法避免引号问题
系统 OOMKilled/137 = 容器内存上限,不是 V8 堆

症状

前端项目打包/构建(webpack、vite、vue-tsc、jest 等)中途崩溃,控制台最后几行是:

<--- Last few GCs --->
.... MB: Mark-Compact ... allocation failure; scavenge might not succeed

<--- JS stacktrace --->
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
----- Native stack trace -----

旧版 Node 上同一错误常写作 FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory。特征:项目越大越容易触发(依赖多/单文件大/tsc 全量类型检查);重试可能偶发通过;发生在 npm run build / vue-tsc / CI 打包阶段。

原因

Node 的 V8 引擎给 JS 堆设了默认上限,超过后 GC 也回收不动就放弃治疗直接崩。默认上限不是固定的 2G:现代 Node(64 位)默认约 4GB(本机 Node 22 实测 heap_size_limit = 4144MB),老版本或 32 位下更小(1.5~2G)——网上大量教程说的「默认 2G」是旧版本事实。构建工具要把整个依赖图 + 编译产物放内存,项目一大就顶到上限。

解法

按推荐顺序选:

  1. 临时提上限(最快),三种写法等效:
  • 命令行:node --max-old-space-size=8192 ./node_modules/vite/bin/vite.js build(或 webpack/vue-tsc 同理);
  • 环境变量(CI/Jenkins/Windows 通用):NODE_OPTIONS=--max-old-space-size=8192,Windows 永久设置用 setx NODE_OPTIONS=--max-old-space-size=8192(注意 setx 永久、新开窗口生效);
  • 写进 package.json:"build": "node --max-old-space-size=8192 ./node_modules/vite/bin/vite.js build";Windows 下注意引号问题可用 cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build。

值按机器内存定(如 4096/8192),别超过物理内存太多,否则变 swap 卡死。

  1. 长期优化(治本):构建缓存(webpack cache / vite 缓存)、代码分割/按需加载、升级构建工具(webpack→vite)、vue-tsc --noEmit 拆到单独阶段、依赖精简。内存压力来自「同时放内存的东西太多」,提上限只是把线抬高。
  2. 区分系统 OOM:若错误是 Killed 或 Exit status 137(容器/CI 里),那是操作系统杀的(cgroup/容器内存上限),调 --max-old-space-size 没用,要加容器内存或减并发。
验证证据
  • 本地实测(2026-08-29,WSL Ubuntu,Node v22.22.1):
  • 默认 heap_size_limit 实测 4144MB(v8.getHeapStatistics),证明「默认 2G」说法对现代 Node 已过时;--max-old-space-size=8192 后为 8240MB;
  • 构造逐步分配大数组的脚本,默认上限运行 → 完整复现 FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory(含 Last few GCs / JS stacktrace / Native stack trace),进程 SIGABRT 退出码 134;
  • node --max-old-space-size=8192 <脚本> → 分配至 6000MB 上限成功退出(退出码 0);
  • NODE_OPTIONS=--max-old-space-size=8192 node <脚本> → 同样成功(退出码 0),证明环境变量写法与 CLI 等效;
  • 文章里的 package.json 改法(node 直调 vite.js)属于 CLI 写法变体,同源已验证。
  • 实测复现日志(2026-08-29)

适用工具 (2)

本问题方案已挂到下列工具的方案页——从工具页也能回到这里,双向可达。

node · 外部工具npm · 外部工具

来源与证据

收录 验证 ✓ 实测验证适用 2 工具
方案含本地实测或来源可复核的解法;未实测项已在文中如实标注。

素材来源:https://www.cnblogs.com/c2g5201314/p/19070905

← 编码代理与终端 问题域 | 问题货架 | 遇到其它问题?去 问题空间 提交求助卡