Some thoughts on garbage collection

Frank Millman frank at chagford.com
Mon Jan 23 02:17:18 EST 2006


Hi all

I don't know whether this will be of interest, but I have just carried
out an exercise that I found useful, so I thought I would share it.

I am writing a multi-user business app, with a multi-threaded server
program to handle client connections. The server should 'serve
forever'. Each client connection is handled within its own thread, and
can run a variety of processes. Each process is a class, and is run by
instantiating it. As each client logs off, or the connection is broken,
the thread is terminated. I wanted to confirm positively that all
objects created by the thread are garbage collected. I was concerned
that if I left a superfluous reference dangling somewhere I might end
up with the equivalent of a memory leak.

I know from previous experience that you cannot confirm deletion of a
class object by printing a message from a __del__() method, if there
are any cyclic references to the object, as it will then not be garbage
collected at all. Therefore I use the 'delwatcher' class that was
explained by Tim Evans in a post on this subject a couple of years ago
-

class DelWatcher:
    def __init__(self,obj):
        self.objrepr = repr(obj)
    def __del__(self):
        print '%s deleted' % self.objrepr

class a:
    def __init__(self):
        self._delwatcher = DelWatcher(self)

You can now see that an object of class a is deleted, even if it has
cyclic references.

I used this technique, and I could see some objects being deleted at
the correct point. Others, however, did not get deleted until the
server program terminated. After some investigation, I found that I was
not generating enough 'dirty' objects to trigger the garbage collector
into running. I fixed that by putting the following lines at the top of
the server program -

import gc
gc.set_threshold(10)  # on my system, the default is 700

Now I can see all objects being deleted at or close to the expected
point, and therefore I am confident that I do not have any leaks.
Obviously delwatcher and set_threshold are temporary measures to prove
a point - I have now removed them.

Is this a sensible approach, or are there easier ways to achieve this?

Frank Millman




More information about the Python-list mailing list