Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 387
Stefano Borini Avatar asked Sep 18 '25 14:09

Stefano Borini


1 Answers

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
like image 176
Martijn Pieters Avatar answered Sep 20 '25 05:09

Martijn Pieters