Python的垃圾回收能保证在所有情况下循环引用对象的回收吗?

2024-06-25 23:55:11 发布

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

这个问题是我先前问的问题的延伸:Python Delegate Pattern - How to avoid circular reference?在阅读了回复之后,我决定澄清我的问题,但被要求单独发表。在

接下来是:

  1. Python文档中的一段话(转载如下)指出,垃圾收集不能保证循环 引用的对象。我发现的一个帖子here暗示了同样的事情。但对我先前问题的回答不一致。那么,我是不是误解了这段话,或者还有进一步的理解 我错过的细节?在
  2. 我想使用弱引用,正如alexmartelli对问题Should I worry about circular references in Python?的答复中所述,可以完全避免在他的回答中提到的垃圾收集循环引用对象的开销?如果是这样,它是如何工作的?在

相关的Python文档暗示了以下来自Python文档的冲突:

CPython implementation detail: CPython currently uses a reference-counting scheme with (optional) delayed detection of cyclically linked garbage, which collects most objects as soon as they become unreachable, but is not guaranteed to collect garbage containing circular references. See the documentation of the gc module for information on controlling the collection of cyclic garbage. Other implementations act differently and CPython may change. Do not depend on immediate finalization of objects when they become unreachable (ex: always close files).

原文的段落可以在这里找到:http://docs.python.org/reference/datamodel.html粗体的设置是我的。在

提前感谢您的回复。在


Tags: oftheto对象文档objectsascpython
2条回答

当它说不能保证收集循环引用时,这正是它的意思。每当数据结构包含循环引用时,引用计数总是非零,这意味着仅引用计数不足以决定何时删除它们。另一方面,在到达每个范围的末尾之后找到所有的循环引用至少需要花费时间。它将涉及到使用非零引用计数来分析所有对象之间的关系。在

也就是说,总的来说,我不认为你会有问题。对于轻量级脚本,可以忽略它。对于其他人,您仍然需要在范围的末尾做一些清理工作(关闭一个文件,甚至删除循环引用),例如在C中,但是它仍然没有C那样令人兴奋

如果出现问题,只需在完成每个数据对象之前删除循环引用。在

我认为具有循环引用的对象不能被保证被收集的最重要原因是,根据设计,Python从不收集具有循环引用的对象,如果它们定义了__del__方法。有一个漂亮的straightforward reason

Python doesn’t collect such cycles automatically because, in general, it isn’t possible for Python to guess a safe order in which to run the __del__() methods.

我不愿意说,这是不可访问的循环引用对象可能无法检测到的唯一原因。可能有一些不寻常的情况会破坏GC的循环检测机制。但是,除非您为您的一个对象定义__del__,否则您很可能是好的。不用担心,如果发现性能问题,可以使用GC的大量调试选项。在

相关问题 更多 >