Reference counting garbage collection

Alex Martelli aleax at aleax.it
Wed Aug 22 12:36:06 CEST 2001


"Simon Brunning" <SBrunning at trisystems.co.uk> wrote in message
news:mailman.998473353.18926.python-list at python.org...
> > From: Paul Rubin [SMTP:phr-n2001 at nightsong.com]
> > Is there any particular reason Python uses reference counting garbage
> > collection (which leaks memory if there's circular structure) instead
> > of Lisp-style garbage collection?
>
> AFAIK, it uses *both* as of Python 2.0. (If I'm wrong, I'm sure that
someone
> will correct me!)

Yes, but it's not "automatic" for a C-written extension
type to participate correctly in the GC implementation:
if instances of the extension type hold PyObject*'s, the
type must make a (small) effort to cooperate with the
garbage collector, which is optional (to ensure old C
extensions keep working).  So, the GC cannot guarantee
that all reference-loop garbage is collected -- for
example, it won't be if a non-cooperating C extension
type object is part of the loop.  Finalizers (__del__)
also give problems to garbage collectors -- last I heard
(not sure if this is still true), a loop is not finalized
if it includes objects with finalizers, because the order
of finalization calls that would work (if any) is not
determined.  (However, such loops are *collected* --
they're just not *finalized*, but rather added to a
list of uncollectable-garbage in module gc -- your
program can look for them there, and finalize them
itself if it knows how do this for those specific
kinds of objects).

Take this with a grain of salt -- I haven't been looking
at gc in quite a while:-).  Anyway, the advantage of
reference counting is clear -- when and if it works,
finalization of an object happens at the very moment
it becomes unreachable, rather than at some later,
unpredictable time.  People used to RC's strengths have
a hard time adapting to the "whenever I get around to
it" attitude of mark-and-sweep GC -- witness the furious
debate among long-time COM programmers when they learned
that .NET would NOT use reference counting but rather
mark-and-sweep (so, no guaranteed finalization time).

Python as a language is migrating from a reference count
background towards m&s GC -- gradually and slowly.  The
Jython implementation is already fully-m&s-GC as it leaves
things up to the JVM, which of course IS m&s.  CPython
still does RC (guaranteed finalization and all) BUT the
*language* doesn't guarantee it any more -- nor does it
absolutely guarantee that all reference loops will be
reclaimed, either (they will in Jython, but some may
escape in CPython, see above).  So you code try/finally,
because relying on finalization-at-deallocation-time is
not portable, AND you avoid reference loops if you can
to avoid THAT can of worms...:-).


Alex






More information about the Python-list mailing list