2

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

4

1 回答 1

2

因为垃圾收集只处理循环引用。引用gc模块文档

由于收集器补充了 Python 中已经使用的引用计数,因此如果您确定您的程序不会创建引用循环,则可以禁用收集器。

CPython 使用引用计数来清理大多数对象。当您将a引用的列表替换为空列表时,旧列表的引用计数降至 0,因此在该点将其删除。删除列表会导致Foo()实例的引用计数也下降到 0,等等。

如果您改为创建循环引用禁用垃圾收集,您将看到数字保持不变:

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

class Bar(object):
    def __init__(self, foo):
        self.foo = foo
于 2013-07-24T11:28:06.460 回答