Skip to content

heap: near oom headroom extension - #390

Draft
IlyasShabi wants to merge 1 commit into
mainfrom
ishabi/near-oom-callback
Draft

heap: near oom headroom extension#390
IlyasShabi wants to merge 1 commit into
mainfrom
ishabi/near-oom-callback

Conversation

@IlyasShabi

Copy link
Copy Markdown

Current behavior

When V8 signals "near the heap limit" occurs the callback raises the heap limit by a fixed heapLimitExtensionSize, up to maxHeapLimitExtensionCount times, so it can capture an allocation profile before the process dies.

Because GetAllocationProfile() itself allocates, it can re-enter the callback while a capture is in progress. The old code handled that reentrant case separately, returning current_heap_limit + heapLimitExtensionSize, falling back to a hard-coded size.

Issues

  • The extension size is constant. There's no relationship between the granted bytes and what V8 actually needs to finish one more GC while the callback runs. Too small → the extension doesn't satisfy the allocation, V8 re-enters or aborts; this is why the default kept getting nudged upward (10 MiB → 20 MiB) without a principled basis.
  • The 10Mb fallback only existed on the reentrant path. On the top-level path the extension was whatever was configured so behavior differed between the first grant and the rescue grants.
  • Reentrant rescue grants were conflated with the top-level budget, making maxHeapLimitExtensionCount mean two different things and the total granted memory hard to reason about.
  • No overflow guard on current_heap_limit + extension.

Proposed solution

Grant near-OOM headroom sized to what V8 needs, like Node.js does — not a fixed constant.

What Node.js does? extends the heap by one young generation, but only after checking there's actually memory available, and caps how many times it grows. https://github.com/nodejs/node/blob/main/src/env.cc#L2105

What this PR does? when no size is set, auto-sizes the extension to one young generation heap_size_limit() - current_heap_limit with a 10 Mb fallback. Rescue extensions during a capture no longer count against the extension budget, and the math is overflow-safe.

@IlyasShabi
IlyasShabi force-pushed the ishabi/near-oom-callback branch from d1e68da to 6875943 Compare August 10, 2026 12:34
@github-actions

Copy link
Copy Markdown

Overall package size

Self size: 2.48 MB
Deduped: 3.19 MB
No deduping: 3.19 MB

Dependency sizes | name | version | self size | total size | |------|---------|-----------|------------| | pprof-format | 2.3.1 | 504.33 kB | 504.33 kB | | source-map | 0.8.0 | 185.66 kB | 185.66 kB | | node-gyp-build | 4.8.4 | 13.86 kB | 13.86 kB |

🤖 This report was automatically generated by heaviest-objects-in-the-universe

@IlyasShabi
IlyasShabi marked this pull request as draft August 10, 2026 12:43
@IlyasShabi IlyasShabi added the semver-minor Usually minor non-breaking improvements label Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

semver-minor Usually minor non-breaking improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant