nodejs / nodejs/node

v24: discarded vm contexts cause OOM; possible V8 backport

Offen
#66,053 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

confirmed-bug v24.x v8 engine vm
Vorherrschende Sprache
JavaScript
Sterne
122k
Forks
37.3k
Ø Merge
4 T. 2 Std.
Gemergte PRs (30 T.)
283

Beschreibung

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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit repro.mjs und führe es unter v24 mit --max-old-space-size=128 aus; vergleiche anschließend v22, v26 und v24 mit --no-concurrent-recompilation. Untersuche die Retainer von IdentityMapBase und die beiden verknüpften V8-Commits, um festzustellen, ob sie verworfene vm-Kontexte behandeln. Als erledigt gilt die Aufgabe, wenn die Reproduktion "Completed" ausgibt, ohne den Heap zu erschöpfen, und verworfene Kontexte eingesammelt werden können.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
javascript, node.js
Bereich
backend
Issue-Typ
Bug
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Aktiv
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.