nodejs / nodejs/node

v24: discarded vm contexts cause OOM; possible V8 backport

未关闭
#66,053 2 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

confirmed-bug v24.x v8 engine vm
主要语言
JavaScript
星标
122k
派生
37.3k
平均合并
4 天 2 小时
30 天内合并 PR
283

描述

Version

v24.21.0

Platform
Linux x86_64, kernel 6.8.0-139-generic
Subsystem

vm, V8

What steps will reproduce the bug?

Save as repro.mjs; run node --max-old-space-size=128 repro.mjs.

import { runInNewContext } from "node:vm";
import { setImmediate } from "node:timers/promises";

const source = `
  globalThis.payload = new Array(1_000_000).fill(0);
  ${Array.from({ length: 30 }, (_, index) => `
    function work${index}(values) {
      let result = 0;
      for (let i = 0; i < values.length; ++i) {
        result += Math.sqrt(values[i] * values[i] + ${index});
      }
      return result;
    }
  `).join("\n")}
  const values = [1, 2, 3, 4, 5];
  for (let i = 0; i < 1000; ++i) {
    ${Array.from({ length: 30 }, (_, index) => `work${index}(values);`).join("\n")}
  }
`;

for (let i = 0; i < 100; ++i) {
  runInNewContext(source + `\n// ${i}`);
  await setImmediate();
}
console.log("Completed");
How often does it reproduce? Is there a required condition?

Repeatedly on v24.15.0, v24.16.0, and v24.21.0. Completes on v22.23.2, v26.8.2, or with --no-concurrent-recompilation on v24.

What is the expected behavior? Why is that the expected behavior?

Print Completed; discarded contexts should be collectible.

What do you see instead?
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
Additional information

This surfaced in jsdom’s WPT runner with the default ~4 GB heap; the smaller limit makes this reproduction quick. Sampled heap retainers point through V8’s IdentityMapBase to realm prototypes, keeping entire windows alive.

Could V8’s “Stop collecting array and object prototypes” change be backported to v24? Its later thread-safety follow-up might also be relevant.

I haven't verified that those commits are the key ones, but it's worth trying.

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从 repro.mjs 开始,在 v24 下使用 --max-old-space-size=128 运行,然后使用 --no-concurrent-recompilation 比较 v22、v26 和 v24。调查 IdentityMapBase 的 retainers 以及相关的两个 V8 commit,以确定它们是否处理了被丢弃的 vm contexts。完成的标准是:复现程序在不耗尽堆的情况下打印 "Completed",并且被丢弃的 contexts 可以被回收。

由索引模型根据 Issue 内容生成。

评估

技术栈
javascript, node.js
领域
backend
Issue 类型
缺陷
难度
5/5
预计耗时
一周以上
活跃度
活跃
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。