v24: discarded vm contexts cause OOM; possible V8 backport
还没有人认领这个 Issue。
- 主要语言
- 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.
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 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