@@ -199,22 +199,22 @@ unreachable:
199199
200200``` pycon
201201>>> import gc
202- >>>
202+ >>>
203203>>> class Link :
204204... def __init__ (self , next_link = None ):
205205... self .next_link = next_link
206- ...
206+ ...
207207>>> link_3 = Link()
208208>>> link_2 = Link(link_3)
209209>>> link_1 = Link(link_2)
210210>>> link_3.next_link = link_1
211211>>> A = link_1
212212>>> del link_1, link_2, link_3
213- >>>
213+ >>>
214214>>> link_4 = Link()
215215>>> link_4.next_link = link_4
216216>>> del link_4
217- >>>
217+ >>>
218218>>> # Collect the unreachable Link object (and its .__dict__ dict).
219219>>> gc.collect()
2202202
@@ -459,11 +459,11 @@ specifically in a generation by calling `gc.collect(generation=NUM)`.
459459>>> # Create a reference cycle.
460460>>> x = MyObj()
461461>>> x.self = x
462- >>>
462+ >>>
463463>>> # Initially the object is in the young generation.
464464>>> gc.get_objects(generation = 0 )
465465[..., <__main__.MyObj object at 0x7fbcc12a3400>, ...]
466- >>>
466+ >>>
467467>>> # After a collection of the youngest generation the object
468468>>> # moves to the old generation.
469469>>> gc.collect(generation = 0 )
@@ -515,45 +515,6 @@ increment. All objects directly referred to from those stack frames are
515515added to the working set.
516516Then the above algorithm is repeated, starting from step 2.
517517
518- Determining how much work to do
519- -------------------------------
520-
521- We need to do a certain amount of work to ensure that garbage is collected,
522- but doing too much work slows down execution.
523-
524- To work out how much work we need to do, consider a heap with ` L ` live objects
525- and ` G0 ` garbage objects at the start of a full scavenge and ` G1 ` garbage objects
526- at the end of the scavenge. We don't want the amount of garbage to grow, ` G1 ≤ G0 ` , and
527- we don't want too much garbage (say 1/3 of the heap maximum), ` G0 ≤ L/2 ` .
528- For each full scavenge we must visit all objects, ` T == L + G0 + G1 ` , during which
529- ` G1 ` garbage objects are created.
530-
531- The number of new objects created ` N ` must be at least the new garbage created, ` N ≥ G1 ` ,
532- assuming that the number of live objects remains roughly constant.
533- If we set ` T == 4*N ` we get ` T > 4*G1 ` and ` T = L + G0 + G1 ` => ` L + G0 > 3G1 `
534- For a steady state heap (` G0 == G1 ` ) we get ` L > 2G0 ` and the desired garbage ratio.
535-
536- In other words, to keep the garbage fraction to 1/3 or less we need to visit
537- 4 times as many objects as are newly created.
538-
539- We can do better than this though. Not all new objects will be garbage.
540- Consider the heap at the end of the scavenge with ` L1 ` live objects and ` G1 `
541- garbage. Also, note that ` T == M + I ` where ` M ` is the number of objects marked
542- as reachable and ` I ` is the number of objects visited in increments.
543- Everything in ` M ` is live, so ` I ≥ G0 ` and in practice ` I ` is closer to ` G0 + G1 ` .
544-
545- If we choose the amount of work done such that ` 2*M + I == 6N ` then we can do
546- less work in most cases, but are still guaranteed to keep up.
547- Since ` I ≳ G0 + G1 ` (not strictly true, but close enough)
548- ` T == M + I == (6N + I)/2 ` and ` (6N + I)/2 ≳ 4G ` , so we can keep up.
549-
550- The reason that this improves performance is that ` M ` is usually much larger
551- than ` I ` . If ` M == 10I ` , then ` T ≅ 3N ` .
552-
553- Finally, instead of using a fixed multiple of 8, we gradually increase it as the
554- heap grows. This avoids wasting work for small heaps and during startup.
555-
556-
557518Optimization: reusing fields to save memory
558519===========================================
559520
0 commit comments