我们可以删除引用循环对象并释放其内存吗?

2024-06-10 22:35:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我读过关于垃圾收集的不同文章。他们说我们需要gc模块来清理引用循环对象。但是我们可以简单地用del来做清洁吗

例如,如果执行以下操作,是否成功释放此引用循环对象的内存?如果是,那么为什么我们需要gc模块呢?如果没有,为什么不呢

>>> x = [1, 2, 3]    
>>> x.append(x)    # create reference cycle
>>> print(x)
[1, 2, 3, [...]]
>>> sys.getrefcount(x)
3


>>> del x[3]
>>> print(x)
[1, 2, 3]
>>> sys.getrefcount(x)
2
>>> del x    # reference count of x goes to 0!

Tags: 模块对象内存createsys文章gc垃圾
1条回答
网友
1楼 · 发布于 2024-06-10 22:35:55

cpython是引用计数。当对象引用计数变为零时,它将被删除-这将与导致减量的代码内联完成。垃圾收集器用于处理对象不可访问但其引用计数不为零的情况。并不是每个循环引用都需要垃圾收集。重要的是该引用如何展开

>>> x = [1, 2, 3] 

我们创建了一个列表并将其绑定到x。列表本身只是内存中的一个匿名对象,但当前可由x访问。让我们调用列表中的实际对象

>>> x.append(x)    # create reference cycle
>>> print(x)
[1, 2, 3, [...]]
>>> sys.getrefcount(x)
3

此时,列表有来自x的引用,它自己的第4个元素和getrefcount参数(当函数返回时该参数消失,留下2个引用)

>>> del x[3]

del实际上并没有删除东西。它可以解开物体。在这种情况下,list的__delitem__函数被称为从它自己的第四个元素解除列表的绑定,留下一个引用

>>> del x

这次delx中取消绑定列表,并从名称空间中删除x。参考计数变为零,列表被删除。垃圾收集器从未解决过

现在让我们把它混合起来

>>> x = [1, 2, 3]    
>>> x.append(x)    # create reference cycle

我们有两个对列表的引用。但这次只是

>>> del x

delx取消列表的绑定并将其引用计数减至1。这还不足以删除列表。现在我们有一个问题列表不再分配给我们可以获得的任何变量。它不在x中,因为x已经不存在了。但它仍在记忆中。这就是垃圾收集器试图解决的问题

我们不能只使用del,因为没有变量来执行del

相关问题 更多 >