You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Found by the adversarial review of PR #511 (#500 GC work); measured, pre-existing (identical numbers at merge-base 8526c10, so not introduced by any of PRs #508-#511).
Symptom
After Race-loser cancellation, vm_live_counts retains ~(4 segments, 2 continuations, 4 IR streams) per Race after run() returns, and gc.collect() x3 does not release them (200 Races -> 800/400/800 retained).
This is the residual class that #500's commit documents: cycles routed exclusively through PyK interiors are deliberately excluded from the GC protocol (clearing a PyK's chain mid-recovery would violate VM invariants), so such cycles are permanently uncollectable.
Impact
Long-lived processes that use Race/timeout patterns heavily (e.g. a live executor racing order-acks against deadlines for days) accumulate native+Python memory linearly with Race count. Short-lived runs are unaffected.
Fix directions (needs design, touches a coupling core)
Or: revisit whether PyK can implement __traverse__ only (no __clear__), letting the cycle collector SEE the cycle while refusing to clear through PyK — needs verification that traverse-without-clear actually enables collection here (it does not by itself; the cycle must be clearable through some other participating object).
Per the repo Change Protocol this is VM-core coupling-core work (continuation lifecycle x arena ownership) and should not be bolted on.
Found by the adversarial review of PR #511 (#500 GC work); measured, pre-existing (identical numbers at merge-base 8526c10, so not introduced by any of PRs #508-#511).
Symptom
After Race-loser cancellation,
vm_live_countsretains ~(4 segments, 2 continuations, 4 IR streams) per Race afterrun()returns, andgc.collect()x3 does not release them (200 Races -> 800/400/800 retained).This is the residual class that #500's commit documents: cycles routed exclusively through
PyKinteriors are deliberately excluded from the GC protocol (clearing a PyK's chain mid-recovery would violate VM invariants), so such cycles are permanently uncollectable.Impact
Long-lived processes that use Race/timeout patterns heavily (e.g. a live executor racing order-acks against deadlines for days) accumulate native+Python memory linearly with Race count. Short-lived runs are unaffected.
Fix directions (needs design, touches a coupling core)
__traverse__only (no__clear__), letting the cycle collector SEE the cycle while refusing to clear through PyK — needs verification that traverse-without-clear actually enables collection here (it does not by itself; the cycle must be clearable through some other participating object).Per the repo Change Protocol this is VM-core coupling-core work (continuation lifecycle x arena ownership) and should not be bolted on.