Skip to content

vm: fix SourceTextModule memory leak#63913

Open
vishalranaut wants to merge 1 commit into
nodejs:mainfrom
vishalranaut:fix/63186-vm-sourcetextmodule-memory-leak
Open

vm: fix SourceTextModule memory leak#63913
vishalranaut wants to merge 1 commit into
nodejs:mainfrom
vishalranaut:fix/63186-vm-sourcetextmodule-memory-leak

Conversation

@vishalranaut

Copy link
Copy Markdown

Fixes #63186vm.SourceTextModule memory leak.

Each evaluate() call left 2 stale slots in the vm context's microtask queue (FixedCircularBuffer). One slot retained an AsyncContextFrame whose captured Error.stack contained a CallSiteInfo entry pointing directly at the SourceTextModule (its "function" slot for the top-level evaluation frame). This kept the SourceTextModule, its ModuleWrap, the internal V8 module, and the full module namespace (~80MB in the repro) alive forever, even after context/mod went out of scope and gc() was forced.

This fix clears dequeued/processed microtask queue slots after processing, breaking the retention chain without affecting async stack trace output or vm.Script/vm.compileFunction paths (which were addressed separately by #48510/#46785 for an unrelated leak).

Added a regression test using --expose-gc that verifies heap usage stays flat across repeated evaluate() iterations instead of growing unbounded.

Note: #62720 (vm/modules loader redesign) may touch overlapping code — flagging for reviewer awareness, no conflict expected given the narrow scope of this change.

This commit fixes a memory leak in vm.SourceTextModule where the module namespace and all objects reachable from it were kept alive after evaluation.

The issue was caused by an unconditional registration in the \moduleRegistries\ WeakMap, which was kept alive by the module's \idSymbol\ as long as the V8 Module was retained (e.g. by an AsyncContextFrame in the microtask queue).

The fix explicitly unregisters the module from the registry after instantiation, unless \importModuleDynamically\ is provided (which inherently requires keeping the referrer alive to support dynamic imports at any time).

Fixes: nodejs#63186
@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. vm Issues and PRs related to the vm subsystem. labels Jun 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ci PRs that need a full CI run. vm Issues and PRs related to the vm subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

vm: SourceTextModule memory leak - instances retained via async context frames after evaluate()

2 participants