@@ -352,29 +352,6 @@ follows these steps in order:
352
352
objects.
353
353
354
354
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
-
378
355
Optimization: incremental collection
379
356
====================================
380
357
@@ -508,6 +485,43 @@ specifically in a generation by calling `gc.collect(generation=NUM)`.
508
485
```
509
486
510
487
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
+
511
525
Optimization: reusing fields to save memory
512
526
===========================================
513
527
0 commit comments