Python是否会垃圾回收在函数范围内不再引用的变量?

时间:2018-12-27 18:22:27

标签: python garbage-collection cpython

在等待长时间运行的函数完成执行时,我开始考虑垃圾回收器是否将清除对不再使用的变量的引用。

例如,我有一个类似的功能:

def long_running_function():
   x = MemoryIntensiveObject()
   print id(x)
   # lots of hard work done here which does not reference x
   return

我对解释器是否足够聪明以至于意识到不再使用x并可以取消引用x感到好奇。测试起来有些困难,因为我可以编写代码来检查其引用计数,但是隐式地引用了它,从而避免了这样做的原因。

我的想法是,也许当函数被解析并生成字节码时,它可能以一种方式生成,即允许它在无法再引用时清理对象。

或者,答案是否简单?只要我们仍处于“可以”使用的范围内,就不会对其进行清理?

1 个答案:

答案 0 :(得分:5)

否,只要在当前作用域中仍定义了引用该对象的名称,CPython就不会对其进行垃圾收集。

这是因为,即使代码中没有引用名称x作为文字,对vars()locals()的调用仍然可以获取本地名称空间字典的副本。 (最后一次引用x之前或之后),因此整个locals命名空间有效地“根”了它引用的值,直到执行离开其作用域为止。

我不确定其他实现如何做到这一点。特别是,在像PyPy,Jython或IronPython这样的JIT编译的实现中,至少在理论上可以执行此优化。实际上,JVM和CLR JIT确实在其他语言上执行了此优化。这些平台上的Python是否能够利用,完全取决于Python代码被编译成的字节码。