什么时候python对象是垃圾收集的候选者?

Dil*_*lon 3

我想弄清楚究竟什么时候python对象是垃圾收集的候选对象.我已阅读了一些文件/帖子,但未能找到明确的答案.

以下面的行为例.这是foo的最后一个引用.foo指向的对象何时可用于垃圾回收?

ret = func(['xyz: ' + foo.name])
Run Code Online (Sandbox Code Playgroud)

将其分解为(可能的)个别步骤:

  1. 创建临时名称引用.
  2. 'xyz:'与name连接,返回值.
  3. list是使用新字符串创建的.
  4. 使用新数组调用函数.
  5. 功能返回.
  6. 结果被分配给ret.
  7. 下一条指令......

对象首先有资格收集哪两个步骤?对象的引用计数何时减少?

如果步骤列表不完整/不正确,请告诉我.我只是试图列举它们,为潜在的参考答案提供一个共同的起点.

小智 5

与其他垃圾收集语言一样,经验法则是:当它无法访问时.这意味着,只要程序(它的任何部分)仍然可以访问它,就不能是gc'd.在那之后,这是公平的比赛.何时(甚至是否)实际回收完全取决于实施.

在您的示例中,名称foo使对象保持活动状态,因为程序仍可在以后的语句中使用它.(理论上,实现可以检测是否不再使用变量,并删除该引用 - 可能使对象更快到达.实际上,这在Python中是不可能的,除非在JIT编译器编译的某些跟踪中.)列表,相反,func如果func在某些可到达的位置(例如,可到达对象的属性或全局变量)中不存储对它的引用,则可能在执行之后或甚至在其期间变得不可达.

请注意,混淆了foo它引用的对象,这在推理垃圾收集时是致命的.没有对象foo,只有一个对象foo在给定的时间点引用(因此,它指的是在不同的时间点引用的一组对象).这很重要:

  • foo可以改变以引用另一个对象,并且它最初引用的对象可能变得不可达.除非你区分这两种情况,否则你不能谈论这种情况.
  • 可能有许多其他对象的引用foo(实际上很可能).在foo超出范围,被馈送del或更改为引用另一个对象之后,可能会使对象保持很长时间.