【发布时间】:2012-04-12 05:42:35
【问题描述】:
我查看了 python 的官方文档,但我似乎找不到参考循环是什么。任何人都可以澄清它对我来说是什么,因为我正在尝试理解 GC 模块。提前感谢您的回复。
【问题讨论】:
标签: python garbage-collection reference-counting cyclic-reference
我查看了 python 的官方文档,但我似乎找不到参考循环是什么。任何人都可以澄清它对我来说是什么,因为我正在尝试理解 GC 模块。提前感谢您的回复。
【问题讨论】:
标签: python garbage-collection reference-counting cyclic-reference
这是一个参考循环:
l = []
l.append(l)
l 的第一个元素,即l[0],现在是对l 本身的循环引用。
【讨论】:
引用循环仅仅意味着一个或多个对象相互引用,这样如果你在纸上用代表依赖关系的箭头将它画出来,你会看到一个循环。
(几乎)最简单的引用循环是有两个对象 a 和 b 相互引用:
a.other = b
b.some_attr = a
天真的垃圾收集器严格根据一个对象是否被另一个对象引用来工作。在这种情况下,如果a 和b 都没有被其他任何东西引用,它们仍然会相互引用,并且天真的垃圾收集器可能不会回收内存。 (不过,我不知道 Python 是否可以被引用循环捕获。)
编辑:最简单的引用循环是引用自身的对象:
a = []
a.append(a)
【讨论】:
>>> x=[1,2,3]
>>> x.append(x)
>>> x
[1, 2, 3, [...]]
>>>
现在这里的变量x引用了自己,这叫做引用循环。
【讨论】:
>>> aRef = []
>>> aRef.append(aRef)
>>> print aRef
[[...]]
这将创建一个由名为aRef 的变量引用的列表对象。列表对象中的first element 是对其自身的引用。在这种情况下,del aRef 将 aRef 取消引用到列表对象。但是,列表对象的引用计数不会减少到零,并且列表对象不会被垃圾回收,因为列表对象仍然引用它自己。在这种情况下,Python 中的垃圾收集器会定期检查是否存在此类循环引用,并由解释器收集它们。以下是手动收集循环引用对象占用空间的示例。
>>> import gc
>>> gc.collect()
0
>>> del aRef
>>> gc.collect()
1
>>> gc.collect()
0
【讨论】: