當測試一個持有弱引用的類時,我偶然發現了一個稍微奇怪的行爲:Python垃圾回收器似乎缺少列表中的最後一個元素。一個最小的例子:垃圾回收器缺少列表中的最後一個值
class Test(object):
def __init__(self, i):
self.i = i
def __del__(self):
print('Deleting Test {0}'.format(self.i))
if __name__ == '__main__':
x = [Test(i) for i in range(5)]
for t in x:
print(t.i)
x = []
上面將打印:
刪除試驗3
刪除試驗2
刪除試驗1
刪除試驗0
這發生任何創建的對象(10,100,1000的列表的大小,等等)。爲了仔細檢查是否屬於這種情況,我試圖強制垃圾收集,並確保在將原始列表設置爲[]
或調用後仍然可以使用對原始列表值的弱引用(並且未標記爲已死) del x
:
import weakref
import gc
z = None
if __name__ == '__main__':
x = [Test(i) for i in range(5)]
for t in x:
print(t.i)
z = weakref.ref(x[4])
x = []
gc.collect(2)
print(z().i)
此外,試圖建立一個大名單(再次)力垃圾收集什麼都不做;例如,在插入上述x = []
和gc.collect(2)
之間的以下:
p = [i for i in range(10000000)]
這發生在兩個Python的2.7.6和3.3.3。我意識到垃圾收集是非確定性的,但這似乎相當可疑。是否有一個特定的原因,最後一個元素沒有被垃圾收集,或者這是一種錯誤的錯誤?
奇怪。我運行了你的代碼,最後一行是'Deleting Test 4'。 Python 2.7和3.4都有相同的輸出。運行Debian測試。 – 2015-02-10 10:12:41
@BasicWolf是的,它仍然顯示GC正在追蹤它 - 當解釋器關閉時它確實在最後收集它。 – Yuushi 2015-02-10 10:14:35