Description
Objects can only be cyclic garbage if they are not reachable.
So, if we can cheaply identify the majority of reachable objects before performing the (relatively slow) cycle detecting pass, we can save a lot of time.
Performing a transitive closure of all objects reachable from global roots (the sys and builtins modules as well as builtin class's dicts and sublasses) plus a transitive closure of all objects reachable from the stacks can eliminate >90% of all objects relatively cheaply.
Initial experiments show a ~3% speedup, with an almost 50% speedup of the most gc-heavy benchmark.
This idea has been proposed a few times.
@nascheme has definitely suggested it before. Perhaps he can add links to any prior discussion and/or experiments?
What makes this more feasible now is that the GC can see the evaluation stack of frames, thanks to #124392, so we would now expect that the vast majority of reachable objects can be cheaply marked, thus improving the efficiency of cycle detection considerably.
Linked PRs
- GH-126491: GC: Mark objects reachable from roots before doing cycle collection #126502
- Revert "GH-126491: GC: Mark objects reachable from roots before doing cycle collection (GH-126502)" #126983
- GH-126491: Increase the threshold for the GC fast cycle test. #126984
- GH-126491: GC: Mark objects reachable from roots before doing cycle collection #127110
- GH-126491: Lower heap size limit with faster marking #127519
- gh-126491: Revert "GH-126491: Lower heap size limit with faster marking (GH-127519)" #127770