Problem entry · machine-readable · 编码代理与终端

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

本页嵌入 #trove-entity JSON(本条目全量结构化数据);全库数据见 /agent/trove.json。

元数据

idnode-heap-oom收录2026-08-29
问题域编码代理与终端主题分组构建与部署
适用工具node · 外部工具npm · 外部工具

症状

前端项目打包/构建(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 卡死。

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

3. **区分系统 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)

来源与证据

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

验证证据:Evidence details kept locally (2026-08-29)