Why does this leak memory?

Ian Kelly ian.g.kelly at gmail.com
Thu Jun 7 18:41:27 EDT 2012


For comparison, here is what a leaking program would look like:

class Foo(object):

    def __init__(self, other=None):
        if other is None:
            other = Foo(self)
        self.other = other

    def __del__(self):
        pass

import gc
gc.set_debug(gc.DEBUG_STATS | gc.DEBUG_LEAK)

for i in range(5):
    foo = Foo()
    del foo
    gc.collect()
    print "len(gc.garbage) ==", len(gc.garbage)


gc: collecting generation 2...
gc: objects in each generation: 167 3363 0
gc: uncollectable <Foo 00B818F0>
gc: uncollectable <Foo 00B81930>
gc: uncollectable <dict 00B80ED0>
gc: uncollectable <dict 00B86270>
gc: done, 4 unreachable, 4 uncollectable, 0.0000s elapsed.
len(gc.garbage) == 4
gc: collecting generation 2...
gc: objects in each generation: 4 0 3463
gc: uncollectable <Foo 00B81910>
gc: uncollectable <Foo 00B81970>
gc: uncollectable <dict 00B861E0>
gc: uncollectable <dict 00B860C0>
gc: done, 4 unreachable, 4 uncollectable, 0.0000s elapsed.
len(gc.garbage) == 8
gc: collecting generation 2...
gc: objects in each generation: 4 0 3467
gc: uncollectable <Foo 00B81950>
gc: uncollectable <Foo 00B819B0>
gc: uncollectable <dict 00B80F60>
gc: uncollectable <dict 00B86030>
gc: done, 4 unreachable, 4 uncollectable, 0.0000s elapsed.
len(gc.garbage) == 12
gc: collecting generation 2...
gc: objects in each generation: 4 0 3471
gc: uncollectable <Foo 00B81990>
gc: uncollectable <Foo 00B819F0>
gc: uncollectable <dict 00B86390>
gc: uncollectable <dict 00B86150>
gc: done, 4 unreachable, 4 uncollectable, 0.0000s elapsed.
len(gc.garbage) == 16
gc: collecting generation 2...
gc: objects in each generation: 4 0 3475
gc: uncollectable <Foo 00B819D0>
gc: uncollectable <Foo 00B81A30>
gc: uncollectable <dict 00B866F0>
gc: uncollectable <dict 00B86420>
gc: done, 4 unreachable, 4 uncollectable, 0.0000s elapsed.
len(gc.garbage) == 20
gc: collecting generation 2...
gc: objects in each generation: 0 0 3475
gc: done, 0.0000s elapsed.


Note that on each iteration, it reports only the four new
uncollectable objects, not any of the previous uncollectable objects,
because when they are found to be uncollectable they are added to
gc.garbage and so become reachable again.

Cheers,
Ian



More information about the Python-list mailing list