@@ -352,29 +352,6 @@ follows these steps in order:
352352 objects.
353353
354354
355- Optimization: marking
356- =====================
357-
358- An object cannot be garbage if it can be reached.
359-
360- To avoid performing the complex algorithm above on the whole heap, we first
361- mark all objects that can be reached from any frame stack or from global
362- objects like the modules or builtin classes.
363-
364- This marking step does much less work per object, so reduces the time spent
365- performing garbage collection by at least half.
366-
367- This mark phase marks all object that are transitively reachable from the
368- roots as follows:
369- * All objects directly referred by any builtin class, the ` sys ` module, the ` builtins `
370- module or any frame stack are added to a working set of reachable objects.
371- * Until this working set is empty:
372- * Pop an object from the set and move it to the reachable set
373- * For each object directly reachable from that object:
374- * If it is not already reachable and it is a GC object, then move it to
375- the working set
376-
377-
378355Optimization: incremental collection
379356====================================
380357
@@ -508,6 +485,43 @@ specifically in a generation by calling `gc.collect(generation=NUM)`.
508485```
509486
510487
488+ Optimization: visiting reachable objects
489+ ========================================
490+
491+ An object cannot be garbage if it can be reached.
492+
493+ To avoid having to identify reference cycles across the whole heap, we can
494+ reduce the amount of work done considerably by first moving most reachable objects
495+ to the ` visited ` space. Empirically, most reachable objects can be reached from a
496+ small set of global objects and local variables.
497+ This step does much less work per object, so reduces the time spent
498+ performing garbage collection by at least half.
499+
500+ > [ !NOTE]
501+ > Objects that are not determined to be reachable by this pass are not necessarily
502+ > unreachable. We still need to perform the main algorithm to determine which objects
503+ > are actually unreachable.
504+
505+ We use the same technique of forming a transitive closure as the incremental
506+ collector does to find reachable objects, seeding the list with some global
507+ objects and the current frame of each stack.
508+
509+ This mark phase moves all objects ` visited ` space, as follows:
510+
511+ 1 . All objects directly referred by any builtin class, the ` sys ` module, the ` builtins `
512+ module and all objects directly referred to from stack frames are added to a working
513+ set of reachable objects.
514+ 2 . Until this working set is empty:
515+ 1 . Pop an object from the set and move it to the ` visited ` space
516+ 2 . For each object directly reachable from that object:
517+ * If it is not already in ` visited ` space and it is a GC object,
518+ then move it to the working set
519+
520+ Before each increment of collection is performed, any stack frames that have been created
521+ since the last increment are added to the working set and above algorithm is repeated,
522+ starting from step 2.
523+
524+
511525Optimization: reusing fields to save memory
512526===========================================
513527
0 commit comments