为什么将列表附加到其自身然后删除会导致内存泄漏

CIs*_*ies 5 python memory-leaks

我找到了此内存泄漏检测代码段,并且想知道它生成的内存泄漏。

import gc

def dump_garbage():
    """
    show us what's the garbage about
    """

    # force collection
    print("\nGARBAGE:")
    gc.collect()

    print("\nGARBAGE OBJECTS:")
    for x in gc.garbage:
        s = str(x)
        if len(s) > 80: s = s[:80]
        print(type(x),"\n  ", s)

if __name__=="__main__":
    import gc
    gc.enable()
    gc.set_debug(gc.DEBUG_LEAK)

    # make a leak
    l = []
    l.append(l)
    del l

    # show the dirt ;-)
    dump_garbage()
Run Code Online (Sandbox Code Playgroud)

为了测试gc内存泄漏检测,作者创建了自己的小内存泄漏:

l = []
l.append(l)
del(l)
Run Code Online (Sandbox Code Playgroud)

为什么会导致泄漏?如我所见,我将拥有一个列表对象,然后是一个嵌套的列表对象,其中内部外部,而不是删除外部。gc是否不知道要删除对原始列表的所有引用,从而导致内部列表泄漏?

Tur*_*son 1

(将我之前的评论编辑为答案。)

链接的文章是 2001 年的。当时,Python 2.x 还是新的,许多人可能仍在使用 Python 1.x。

Python 1.x 仅依赖引用计数进行垃圾回收,而循环引用是这种失败的教科书示例。Python 2.x 添加了循环检测步骤,但仍然存在一些问题,例如存在__del__阻塞垃圾收集器的方法,因为它无法找出正确的销毁顺序。从 Python 3.4 开始,大部分问题已经得到解决

那么为什么示例代码仍然显示泄漏呢?它设置一个GC_DEBUG_LEAK标志,除其他外,明确告诉垃圾收集器保留无法访问的对象!