我试图弄清楚 python 对象究竟何时是垃圾收集的候选对象。我已经阅读了一些文档/帖子,但一直无法找到明确的答案。
以下面一行为例。这是对 foo 的最后一次引用。 foo 指向的对象什么时候可用于垃圾回收?
ret = func(['xyz: ' + foo.name])
将其分解为(可能的)各个步骤:
- 已创建名称的临时引用。
- 'xyz: ' 与名称连接并返回值。
- 使用新字符串创建列表。
- 用新数组调用函数。
- 函数返回。
- 结果分配给ret。
- 下一条指令...
在哪两个步骤之间,对象最先有资格被收集?对象的引用计数何时减少?
如果步骤列表不完整/不正确,也请告诉我。我只是试图列举它们,以便为引用的潜在答案提供一个共同的起点。
最佳答案
与其他垃圾收集语言一样,经验法则是:无法访问时。这意味着,只要程序(它的任何部分)仍然可以访问它,就不能对其进行 gc。在那之后,这是公平的游戏。何时(甚至是否)实际上回收完全取决于实现。
在您的示例中,名称 foo
使对象保持事件状态,因为程序仍然可以在以后的语句中使用它。 (理论上,实现可以检测变量是否不再使用,并删除该引用——可能使对象更快无法访问。实际上,这在 Python 中是不可能的,除非在 JIT 编译器编译的某些跟踪中可能除外。)列表,相反,在 func
执行之后,甚至在执行期间,如果 func
没有在某些可访问的位置存储对它的引用(例如,可访问对象的属性),则可能变得无法访问, 或全局变量)。
请注意,您混淆了 foo
和它所指的对象,这在推理垃圾回收时是致命的。没有对象 foo
,只有 foo
在给定时间点引用的对象(因此,它在不同时间点引用的一组对象) .这很重要:
foo
可能会更改为引用另一个对象,而它最初引用的对象可能变得无法访问。除非你区分这两者,否则你不能谈论这种情况。foo
指向的对象可能还有许多其他引用(实际上很有可能)。在foo
超出范围、被提供给del
或更改为引用另一个对象后,对象可能会保持存活很长时间。
关于python - python 对象什么时候成为垃圾收集的候选对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13690226/