[Python-Dev] Garbage collector problem

Tim Peters tim.one@comcast.net
Fri, 28 Jun 2002 17:49:58 -0400

[Jeremy, to Kevin Jacobs]
> ...
> Your suggestion seems to be that we should treat references from older
> generations to newer generations as external roots.

That's the way it works now:  an object in gen N *is* an external root wrt
any object it references in gen I with I < N.

> So a cycle that spans generations will not get collected until
> everything is in the same generation.

Right, and that's what happens (already).  When gen K is collected, all gens
<= K are smushed into gen K at the start, and all trash cycles are collected
except for those that contain at least one object in gen K+1 or higher.

> Indeed, that does not seem harmful.

It hasn't been so far <wink>, although you can certainly construct cases
where it causes an inconvenient delay in trash collection.

> On the other hand, it's hard to reconcile an intuitive notion of
> generation with what we're doing by running GC over and over as you
> add more elements to your list.  It doesn't seem right that your list
> becomes an "old" object just because a single function allocates 100k
> young objects.  That is, I wish the notion of generations accommodated
> a baby boom in a generation.

I don't think you do.  Pushing the parent object into an older generation is
exactly what's supposed to save us from needing to scan all its children
every time a gen0 collection occurs.

Under 2.2.1, Kevin's test case pushes "the list" into gen2 early on, and
those of the list's children that existed at that time are never scanned
again until another gen2 collection occurs.  For a reason I still haven't
determined, under current CVS "the whole list" is getting scanned by
move_root_reachable() every time a gen0 collection occurs.  It's also
getting scanned by both subtract_refs() and move_root_reachable() every time
a gen1 collection occurs.  I'm not yet sure whether the mystery is why this
happens in 2.3, or why it doesn't happen in 2.2.1 <0.5 wink>.