Measured on the compiled claude-code TUI during the cc performance campaign (instrument: PERRY_GC_CENSUS + [gc-idle-compact] diagnostics, binary built from main 12efed1222).
What happens
The idle compaction pass selects 10,740 pages, predicts 44 MB releasable, runs for 228 ms, and releases 0 bytes.
Why
Selection works in page granules while the release path works in blocks. selected_releasable_block_bytes is computed from page granules despite its name, so the prediction can never be met: a page being releasable says nothing about whether every page of its enclosing block is, and only whole blocks are returned.
Why it matters
228 ms of a pause budget on a TUI whose idle CPU is already 150-390x node's, spent for nothing. The same window is where the process is otherwise pinned in layout work, so this is pure loss. On this workload the pass should either be made block-targeted or stopped.
Suggested direction
Either make selection block-targeted — score whole blocks by the releasability of every page they contain, so the prediction is achievable by construction — or gate the pass off until it can be. Whichever is chosen, the pass needs a released-bytes counter checked against its own prediction, so a pass that predicts 44 MB and returns nothing fails visibly instead of silently costing 228 ms. Related: the two-observation empty-block release rule cannot fire either, because arena::reset::reset_region_to_zero clears dead_cycles on every block including already-empty ones, and cc's release path is the incremental GeneralResetState whose per-block snapshot any mid-cycle minor invalidates (that fix was built behind a flag and measured flat — do not rebuild it as-is).
Context: at the same sample the arena held 194-217 MB of capacity for 46-84 MB live, with 53-59 MB sitting in 51-56 empty eden blocks holding 1-9 MB of objects.
https://claude.ai/code/session_01YPfnmWZmSpSWpmnoXvH8z2
Measured on the compiled claude-code TUI during the cc performance campaign (instrument:
PERRY_GC_CENSUS+[gc-idle-compact]diagnostics, binary built from main12efed1222).What happens
The idle compaction pass selects 10,740 pages, predicts 44 MB releasable, runs for 228 ms, and releases 0 bytes.
Why
Selection works in page granules while the release path works in blocks.
selected_releasable_block_bytesis computed from page granules despite its name, so the prediction can never be met: a page being releasable says nothing about whether every page of its enclosing block is, and only whole blocks are returned.Why it matters
228 ms of a pause budget on a TUI whose idle CPU is already 150-390x node's, spent for nothing. The same window is where the process is otherwise pinned in layout work, so this is pure loss. On this workload the pass should either be made block-targeted or stopped.
Suggested direction
Either make selection block-targeted — score whole blocks by the releasability of every page they contain, so the prediction is achievable by construction — or gate the pass off until it can be. Whichever is chosen, the pass needs a released-bytes counter checked against its own prediction, so a pass that predicts 44 MB and returns nothing fails visibly instead of silently costing 228 ms. Related: the two-observation empty-block release rule cannot fire either, because
arena::reset::reset_region_to_zeroclearsdead_cycleson every block including already-empty ones, and cc's release path is the incrementalGeneralResetStatewhose per-block snapshot any mid-cycle minor invalidates (that fix was built behind a flag and measured flat — do not rebuild it as-is).Context: at the same sample the arena held 194-217 MB of capacity for 46-84 MB live, with 53-59 MB sitting in 51-56 empty eden blocks holding 1-9 MB of objects.
https://claude.ai/code/session_01YPfnmWZmSpSWpmnoXvH8z2