feat(timing): time garbage-collection pauses in the frame stats (#722)

A GcMonitor in src/common/frame_timing.py, installed once per process from gc.callbacks by the display manager (and render_bench), counts collections and seconds per generation, the longest, and those of 20 ms or more. A long one tags the next presented frame 'gc' in record(), so frame_soak shows its late rate under 'after work'; the stats file gains an additive 'gc' block printed as a 'Garbage collection' line; and a Render stall dump says when a long collection ran inside the stall. Diagnostic only: nothing tunes, freezes or disables the collector.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Chuck
2026-10-01 21:29:08 -04:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 85be4bf25d
commit 5aa7a63127
7 changed files with 288 additions and 4 deletions
+3 -2
View File
@@ -57,7 +57,7 @@ import freetype
from src.common import snapshot_policy
from src import display_watchdog
from src.common.frame_timing import FrameTimingRecorder
from src.common.frame_timing import FrameTimingRecorder, install_gc_monitor
if TYPE_CHECKING:
from src.common.render_gate import RenderGate
@@ -365,7 +365,8 @@ class DisplayManager:
# Timing of every presented frame, whoever drew it, for
# scripts/frame_soak.py. See src/common/frame_timing.py.
self.frame_timing = FrameTimingRecorder(info=self._frame_timing_info())
self.frame_timing = FrameTimingRecorder(
info=self._frame_timing_info(), gc_monitor=install_gc_monitor())
self.frame_timing.scrolling_now = self._scrolling_now
self._scrolling_state = {