【问题标题】:Garbage collector missing last value in list垃圾收集器缺少列表中的最后一个值
【发布时间】:2015-02-10 10:09:16
【问题描述】:

在测试一个包含弱引用的类时,我偶然发现了这个有点奇怪的行为: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 = []

上面将打印:

0

1

2

3

4

删除测试 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 测试中运行。
  • @BasicWolf 是的,GC 似乎仍在跟踪它——当解释器关闭时,它确实会在最后收集它。

标签: python garbage-collection


【解决方案1】:

您的第一个源代码中的变量t 仍然存在,并包含对最后一个条目的引用。调用del t 后,最后一个Test 对象将被删除。

【讨论】:

    猜你喜欢
    • 2023-03-07
    • 1970-01-01
    • 2013-01-24
    • 2018-10-21
    • 1970-01-01
    • 2011-07-16
    • 2013-08-24
    • 2018-12-30
    • 1970-01-01
    相关资源
    最近更新 更多