Skip to content

memory(gc): critical pressure and device budgets do not drain or bound the per-thread 64 MiB block pool #7875

Description

@proggeramlug

Summary

The recycled arena-block pool introduced for #7438 is a fixed 64 MiB per live thread cache. Every normal general/old/large-Eden block-deallocation path offers blocks to it before actually deallocating them.

That conflicts with two current contracts:

  1. js_gc_memory_pressure(level >= 2) documents that critical pressure runs a full cycle so idle blocks are handed back to the OS.
  2. PERRY_GC_HEAP_LIMIT / the device-derived budget scales collector thresholds for small devices and containers.

The pool has no drain API, is not consulted by the pressure entry point, and does not scale with the heap budget. On Unix it uses MADV_FREE, which leaves mappings cached and may leave pages resident until the OS reclaims them; on non-Unix platforms there is no equivalent discard in this path. A live thread can therefore retain up to 64 MiB of pooled mappings after a critical-pressure full GC, and N live agent threads can retain up to N × 64 MiB independently.

Evidence

The last point also makes current deallocated_bytes / “freed back to OS” diagnostics overstate physical release after #7438.

Proposed direction

  • Add an explicit current-thread pool drain/bypass for critical memory pressure and allocation-failure recovery.
  • Scale the normal pool cap from the device heap budget, and decide whether a process-wide cap is needed for perry/thread agents.
  • Separate “removed from arena accounting”, “pooled/discarded”, and “actually deallocated/unmapped” telemetry.

Acceptance criteria

  • After a synchronous level-2 pressure call, the current thread's pool is empty (or bounded by a documented small emergency reserve) and its blocks have gone through real deallocation/unmapping where the platform supports it.
  • Deferred critical pressure drains the pool when the owed full collection completes.
  • A small PERRY_GC_HEAP_LIMIT cannot coexist with a larger fixed per-thread pool allowance.
  • Tests seed the pool, exercise synchronous and deferred critical pressure, and assert pool bytes plus honest release telemetry.
  • Add a multi-thread/process-level retention test or telemetry assertion preventing N × 64 MiB silent growth across live agents.

Metadata

Metadata

Assignees

Labels

bugConfirmed defect or regressionperformanceRuntime, compile-time, build-size, or memory performance

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions