On Aug 5, 5:23 am, Terry Reedy <[EMAIL PROTECTED]> wrote: > To understand this, it helps to realize that Python functions are not, > in themselves, recursive. Recursiveness at any time is a property of a > function in an environment, which latter can change. More specifically, > a function call is recursive if the expression indicating the function > to call happens to indicate the function containing the call at the time > of evaluation just before the evaluation of the argument expressions.
I didn't realize that the function looks up itself in the outer environment when it makes the recursive call, instead of at definition time. > Adding 'inner = None' at the end of an outer function will break the > cycle and with CPython, all will be collected when outer exits. I think I'll use that for inner functions that do need to access the outer environment, but do not need to live longer than the call to the outer function. > Not a bug, but an educational example and possibly useful to someone > running on CPython with gc turned off and making lots of calls to > functions with inner functions with recursive references. I learned a > bit answering this. That describes our application: in some cases, we have several gigabytes of small objects, in which case mark-and-sweep garbage collection takes quite a long time, especially if some of the objects have been pushed into the swap. I have broken all cycles in our own data structures a while ago, but got an unexpected memory leak because of these cyclic references from inner functions. Thanks for your clear explanation! Bye, Maarten -- http://mail.python.org/mailman/listinfo/python-list