Stefano Borini
Stefano Borini

Reputation: 143785

Why is python collecting even if gc disabled?

This code

import gc
gc.disable()
print gc.isenabled()
print len(gc.get_objects())
class Foo(): pass
print len(gc.get_objects())

a=[]
print len(gc.get_objects())
for i in xrange(10000):
    a.append(Foo())

print len(gc.get_objects())
a=[] # Should not collect
print len(gc.get_objects())
gc.collect()
print len(gc.get_objects())

Produces this output

False
3754
3755
3756
13756
3756
3374

I would expect the second to last number to be 13756, because the gc is disabled and when the original a list goes out of scope, it should not drop those objects. Apparently python is collecting those objects anyway. Why ?

python is 2.7.2

Upvotes: 4

Views: 359

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121724

Because garbage collection only deals with circular references. Quoting from the gc module documention:

Since the collector supplements the reference counting already used in Python, you can disable the collector if you are sure your program does not create reference cycles.

CPython uses reference counting to clean up most objects. When you replace the list a referred to with an empty list, the reference counts for the old list dropped to 0, so it is deleted at that point. Deleting the list causes the reference counts for the Foo() instances to drop to 0 too, etc.

If you create circular references instead, and disable garbage collection, you'll see the numbers remain constant:

class Foo(object):
    def __init__(self):
         self.bar = Bar(self)

class Bar(object):
    def __init__(self, foo):
        self.foo = foo

Upvotes: 4

Related Questions