Garbage collection of recursive inner function

from.future.import at from.future.import at
Mon Aug 4 18:49:20 CEST 2008


I encountered garbage collection behaviour that I didn't expect when
using a recursive function inside another function: the definition of
the inner function seems to contain a circular reference, which means
it is only collected by the mark-and-sweep collector, not by reference
counting. Here is some code that demonstrates it:

def outer():

	def inner(n):
		if n == 0:
			return 1
			return n * inner(n - 1)

	return 42

import gc
print outer()
print gc.garbage

Output when executed:
$ python
[<cell at 0xb7dec3ec: function object at 0xb7dbd3ac>, (<cell at
0xb7dec3ec: function object at 0xb7dbd3ac>,), <function inner at

Note that the inner function is not called at all, it is only defined.
If the inner function is moved outside the scope of the outer
function, gc.garbage will be empty. If the inner function is inside
but not recursive, gc.garbage will also be empty. If the outer
function is called twice, there will be twice as many objects in

Is this expected behaviour? Collecting an object when its refcount
reaches zero is preferable to collecting it with mark-and-sweep, but
maybe there is a reason that a circular reference must exist in this
situation. I want to check that first so I don't report a bug for
something that is not a bug.


More information about the Python-list mailing list