Next.js 开发服务器为何会 JavaScript heap out of memory?

👁 24 次阅读

Next.js 开发服务器为何会 JavaScript heap out of memory?

来源:https://github.com/vercel/next.js/issues/82511

现象描述

该 issue 的标题区域直接给出了复现代码仓库链接 https://github.com/NeoSahadeo/Avg-NextJS-experience,复现步骤为运行 pnpm run dev 或 pnpm next dev。报告者贴出的是 Node.js 进程在开发阶段堆内存耗尽后崩溃的完整输出,其中关键行为如下:
<--- Last few GCs --->

[3314:0xde692d0]   178177 ms: Scavenge 2024.1 (2060.6) -> 2016.6 (2060.6) MB, 4.90 / 0.00 ms  (average mu = 0.692, current mu = 0.515) allocation failure;
[3314:0xde692d0]   178198 ms: Scavenge 2024.3 (2060.6) -> 2016.7 (2060.8) MB, 4.67 / 0.00 ms  (average mu = 0.692, current mu = 0.515) allocation failure;
[3314:0xde692d0]   181163 ms: Mark-Compact 2617.4 (2653.9) -> 2214.5 (2274.8) MB, 2633.36 / 0.00 ms  (average mu = 0.565, current mu = 0.404) allocation failure; scavenge might not succeed

<--- JS stacktrace --->

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
崩溃前的 GC 日志显示,堆内存在约 2GB 附近反复进行 Scavenge,随后 Mark-Compact 将占用推高至 2617.4 MB,且单次压缩耗时 2633.36 ms,scavenge might not succeed 表明回收已难以跟上分配速度。报告者贴出的第二段日志来自另一个进程([4029:0x19bec2d0]),呈现相同的增长轨迹,说明这不是单次偶然崩溃。 讨论首先集中在版本差异上。报告者 NeoSahadeo 在 2025-08-10 给出明确对照: > Does not work: next@15.4.5 next@15.4.4 next@15.4.3 next@15.4.2 next@15.4.1 Does work: next@15.4.0 也就是说,同一个项目在 15.4.0 正常,从 15.4.1 起持续崩溃。这条版本区间是整条 issue 中最早的定位线索。

背景原因

icyJoseph 在 2025-08-11 尝试用 StackBlitz 直接加载该仓库(https://stackblitz.com/github/NeoSahadeo/Avg-NextJS-experience),结果是「It runs without problem here」,即在该环境中无法复现。随后追问是否换过包管理器或 pnpm 版本。报告者于 2025-08-12 回复已试过 npm 与 deno,「both have the same outcome」。icyJoseph 同日再次确认「a project that small should just run, as the stackblitz shows」,并建议尝试 pnpm next dev --turbo,同时要求提供更多错误栈信息。 这一段讨论确立了两个事实:崩溃与包管理器无关,且在较小项目上仍会出现;但第三方托管环境未能复现,说明触发条件依赖本地环境或依赖树的具体状态。 讨论后期出现了两类可能方向的假设。fabio-nettis 在 2025-11-19 提出需要「metrics or target repository」来缩小原因,并追问涉及的是 turbopack、cache components、哪些依赖、Node.js 版本以及 next 配置文件里启用了哪些 flag。chrisneven 同日回复,按建议用 --webpack 选项关掉 turbopack 运行同一页面仍然崩溃,因此无法确认 turbopack 的相关性。这条反馈对「问题只出在 Turbopack」的假设构成反证。 另一条线索来自依赖版本不一致。xollaborator 在 2025-12-04 报告: > In our case, the reason of this error was that a dependency used zod 4.1.13 and we had zod 4.1.11 in package.json. Once both versions were the same, out of memory did not appear. 这是社区侧给出的具体成因与缓解方式,属于个案结论。fabio-nettis 与 RazmikDev 随后追问如何定位该依赖版本不一致,说明这条线索被多位参与者视为有效方向,但尚未形成通用结论。

排查或量化方法

issue 中实际出现过的排查动作可以按以下条目归纳,均为讨论中有人执行或建议过的:
  • 版本二分:在 15.4.0 与 15.4.1~15.4.5 之间对照,确认崩溃起点(报告者执行)。
  • 更换包管理器:npm、deno 均复现同样结果(报告者执行)。
  • 在托管环境(StackBlitz)加载同一仓库,未能复现(icyJoseph 执行)。
  • 关闭 Turbopack:使用 --webpack 选项运行同一页面,仍崩溃(chrisneven 执行)。
  • 采集追踪:fabio-nettis 引用官方文档页面 https://nextjs.org/docs/app/guides/local-development#turbopack-tracing 建议产出 trace 以定位问题。
  • 核对依赖树中同名包的多版本共存,例如 zod 的 4.1.13 与 4.1.11 并存(xollaborator 的个案)。
量化方面,崩溃日志本身提供了可用指标:堆占用在崩溃前达到约 2617.4 MB,Mark-Compact 单次耗时 2633.36 ms,进程存活约 178~184 秒。AlexHaffer 在 2026-03-28 的补充把量级说得更直接:进程在崩溃前「genuinely consumes ~7.5GB heap」,而 Activity Monitor 中显示的实际内存占用看起来较低。这类「观测工具读数与 V8 堆上限不一致」的现象,是本 issue 中反复被提到的迷惑点。

当前处理路径与局限

该 issue 当前状态为 open,标签为 Runtime,共 44 条评论,最后一条评论日期为 2026-03-28。官方尚未合入修复方案,也未见维护者在讨论中确认根因,因此不存在可复制的确定性修复步骤。可用的处理路径全部来自讨论中的社区尝试,均带有明确局限:
  • 回退版本:按报告者的对照,15.4.0 可用,15.4.1 及以上不可用。局限是版本跨度大,且后续复现报告显示问题在更高版本依然存在,回退不是长期方案。
  • 统一依赖版本:据 issue 讨论,某项目因依赖使用 zod 4.1.13 而自身锁定 4.1.11,统一版本后 OOM 不再出现。局限是这属于单点个案,fabio-nettis 在 2026-01-05 明确表示即便「bumping and ensuring dependency consistency」,其项目仍会遇到该问题,说明统一版本并非通用解法。
  • 关闭 Turbopack:讨论中有人以 --webpack 尝试,未解决崩溃,因此该路径在已有反馈中无效。
  • 产出 trace 供分析:fabio-nettis 建议按 turbopack tracing 文档采集,但讨论中未见有人回帖给出 trace 结果,该方向仍停留在建议阶段。
需要特别指出的是,AlexHaffer 在 2026-03-28 的上报对上述部分假设构成挑战:其在 Next.js 16.2.1、TURBOPACK=0、Node v22.22.2、Apple Silicon(darwin-arm64)环境下仍复现崩溃,且项目中「There is no zod dependency」。该条还说明栈追踪一致指向 @next/swc-darwin-arm64。这既排除了 zod 作为必要条件,也说明关闭 Turbopack 不足以规避问题。官方侧对该条尚无公开回应。

参数或对比表格

下表汇总 issue 中出现的环境与结果对照,仅收录讨论中明确写出的组合。
环境或配置结果来源
next@15.4.0可用NeoSahadeo,2025-08-10
next@15.4.1 / 15.4.2 / 15.4.3 / 15.4.4 / 15.4.5崩溃NeoSahadeo,2025-08-10
npm、deno 作为包管理器同样崩溃NeoSahadeo,2025-08-12
StackBlitz 托管加载同一仓库无法复现,正常运行icyJoseph,2025-08-11
--webpack 关闭 Turbopack仍崩溃chrisneven,2025-11-19
zod 版本统一为同一版本OOM 不再出现(个案)xollaborator,2025-12-04
统一依赖版本后仍崩溃fabio-nettis,2026-01-05
next 16.0.3,node v22.21.1,kernel 6.17.7-zen1-1-zen正常运行NeoSahadeo,2025-11-19
Next.js 16.2.1,TURBOPACK=0,Node v22.22.2,darwin-arm64,无 zod 依赖仍崩溃,栈指向 @next/swc-darwin-arm64AlexHaffer,2026-03-28
表中 16.0.3 正常与 16.2.1 崩溃并不矛盾,它们是不同项目、不同平台上的独立观察,不应合并为单一结论。

常见错误排查

  • 误判为包管理器问题。讨论中已用 npm 与 deno 验证结果一致,更换包管理器不能规避,排查重点应放在依赖树与运行时版本上。
  • 误判为 Turbopack 专属。--webpack 与 TURBOPACK=0 两种关闭方式下均有崩溃报告,不能把关闭 Turbopack 当作修复手段。
  • 只看系统监视器内存。崩溃日志中的堆占用与 Activity Monitor 读数存在明显差距,AlexHaffer 描述为堆已到约 7.5GB 而系统视图偏低,判断时应以 GC 日志与 FATAL ERROR: Reached heap limit 为准。
  • 认为小项目不会触发。icyJoseph 明确指出该项目「that small should just run」,但报告者侧持续复现,项目规模不是判据。
  • 把个案的 zod 版本统一当作通用修复。已有用户在统一版本后仍崩溃,该做法只在特定依赖组合下有效。

实践建议

遇到同类崩溃时,先固定可用的版本基线。本 issue 中 15.4.0 与 16.0.3 分别有正常运行记录,可作为对照起点,再向崩溃版本做二分。判断是否命中同一问题时,优先比对崩溃前的 GC 行形态:连续 Scavenge 停留在 2GB 附近、随后 Mark-Compact 推高到 2600MB 量级、并出现 scavenge might not succeed,与本文摘录的日志高度一致。若栈追踪指向平台相关的原生包(如 @next/swc-darwin-arm64),应把平台与 Node.js 版本一并记录进复现报告。 对依赖侧,检查是否存在同名包的多版本共存,尤其是讨论中被点名的 zod。这一动作成本低,即便不是根因也能排除一类变量。若准备上报,按 fabio-nettis 的建议附带依赖清单、Node.js 版本、next 配置中的 flag 状态以及 trace,比只贴 GC 日志更有助于定位。需要注意,关闭 Turbopack 并不能作为验证手段的终点,讨论中两种关闭方式都未改变崩溃结果。

FAQ

这个 OOM 是 Next.js 的已知修复问题吗? 不是。issue #82511 当前状态为 open,官方未合入修复方案,讨论中也无维护者确认根因。所有可用做法均来自社区尝试,属于缓解而非官方修复。 从哪个版本开始出现? 据报告者在 2025-08-10 的对照,next@15.4.0 可用,15.4.1 至 15.4.5 均崩溃。后续在 Next.js 16.2.1 上仍有复现报告。 关闭 Turbopack 能解决吗? 不能。讨论中有人用 --webpack 运行同一页面仍崩溃,另有用户在 TURBOPACK=0 下复现,两种方式均未规避。 统一 zod 版本是通用解法吗? 据 issue 讨论,有用户因依赖使用 zod 4.1.13 而自身为 4.1.11 导致该错误,统一后消失;但同时有用户表示在确保依赖一致后仍崩溃,且另有复现者项目中没有 zod 依赖,因此不是通用解法。 崩溃时堆占用大概是多少? 摘录的 GC 日志显示崩溃前 Mark-Compact 达到约 2617.4 MB,单次压缩耗时 2633.36 ms;另一条上报称进程在崩溃前实际消耗约 7.5GB 堆。不同环境读数不同,应以各自 GC 日志为准。

订阅 AI 百事知

每周精选 AI 工具评测、行业资讯与使用教程,第一时间送达。

🔗 相关阅读(你可能还想看)

📄 Outlook 节点创建草稿添加附件为何报 UnableToDeserializePostBody?
📄 Flowise 点击市场或聊天页为何整页白屏?
📄 如何解决 Azure AI Search 向量存储的 $filter 递归深度超限错误?
📄 如何解决 shadcn/ui Sidebar 与 Header 重叠的问题?
📄 Nuxt 偶发 Cannot read properties of undefined 报错是怎么回事
📄 如何解决「Visual Studio Code for ipad」相关的问题?
📄 如何在AutoGen中实现企业级代理治理的加密行动收据(AAR)?
📄 记忆内容未清洗直接注入系统提示词,如何防范间接提示注入?
crewAI LiteAgent 将记忆内容直接拼接到系统提示词,存在间接提示注入风险。社区提出分层防御方案,但 iss
📄 如何在 Vite 中忽略 node_modules 却仍监视某个子包?
Vite 官方文档示例配置无法生效,chokidar 底层排除逻辑导致否定模式失效。社区提供 5 种变通方案,各有局限,
🤖 想直接和 AI 对话?
免费体验 DeepSeek V4 等顶级模型,无需注册,随问随答
🎯 立即体验 AI 工具

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

🤖 嘟嘟客服
滚动至顶部
🤖 嘟嘟客服
🤖 嘟嘟客服
';i.value='';m.innerHTML+='
...
';fetch('/dify-chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({query:q,user:'w'+Date.now()})}).then(function(r){return r.json()}).then(function(d){var a=d.answer||'暂时无法回复';m.removeChild(m.lastChild);m.innerHTML+='
'+a+'
'}).catch(function(){m.removeChild(m.lastChild);m.innerHTML+='
网络异常
'})">发送