Reputation: 77
While waiting for a long running function to finish executing, I began thinking about whether the garbage collector will clean up references to variables which will no longer be used.
Say for example, I have a function like:
def long_running_function():
x = MemoryIntensiveObject()
print id(x)
# lots of hard work done here which does not reference x
return
I'm intrigued whether the interpreter is smart enough to realize that x is no longer used and can be dereferenced. It's somewhat hard to test, as I can write code to check its reference count, but that implicitly then references it which obviates the reason for doing it.
My thought is, perhaps when the function is parsed and the bytecode is generated, it may be generated in such a way that will allow it to clean up the object when it can no longer be referenced.
Or, is the answer just simpler that, as long as we're still within a scope where it "could" be used, it won't be cleaned up?
Upvotes: 4
Views: 554
Reputation: 60957
No, CPython will not garbage collect an object as long as a name that references that object is still defined in the current scope.
This is because, even if there are no references to the name x
as literals in the code, calls to vars()
or locals()
could still grab a copy of the locals namespace dictionary (either before or after the last reference to x
) and therefore the entire locals namespace effectively "roots" the values it references until execution leaves its scope.
I don't know for certain how other implementations do this. In particular, in a JIT-compiled implementation like PyPy, Jython, or IronPython, it is possible at least in theory for this optimization to be performed. The JVM and CLR JITs actually do perform this optimization in practice on other languages. Whether Python on those platforms would be able to take advantage or not depends entirely on the bytecode that the Python code gets compiled into.
Upvotes: 6