2013-07-24 2 views
2

Этого кодПочему сбор python, даже если gc отключен?

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, потому что дс отключается, и когда первоначальный a список выходит из области видимости, это не следует отбрасывать эти объекты. Очевидно, что python все равно собирает эти объекты. Зачем ?

питон 2.7.2

ответ

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 
+0

D'oh! Спасибо. Очень интересно. –

+0

Как я могу получить информацию о недоступных объектах и ​​когда они будут собраны? –

+0

['gc.garbage'] (http://docs.python.org/2/library/gc.html#gc.garbage) дает вам список объектов, которые могут быть * не * собраны; нет API для перечисления чего-либо недоступного и * может * собираться, потому что для этого потребуется явный запуск коллекции, который затем разбивает циклы в это время. Вы можете установить пороговые значения, которые будут влиять на выполнение цикла, но вы не можете запросить, когда он будет запущен, потому что он не основан на времени. –

Смежные вопросы