此代码
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())
生成此输出
False
3754
3755
3756
13756
3756
3374
我希望倒数第二个数字为13756,因为gc已被禁用,当原始a
列表超出范围时,它不应删除这些对象。显然python正在收集这些对象。为什么?
python是2.7.2
答案 0 :(得分:2)
因为垃圾收集只处理循环引用。引自gc
module documention:
由于收集器补充了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