Reputation: 143785
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
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