From b7ba7433126bff12dd638f11f831fa7bfd0bbf4a Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Sat, 13 Apr 2002 05:21:47 +0000 Subject: SF bug 543148: Memory leak with stackframes + inspect. Put a bound on the number of frameobjects that can live in the frameobject free_list. Am also backporting to 2.2. I don't intend to backport to 2.1 (too much work -- lots of cyclic structures leak there, and the GC API). --- Objects/frameobject.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 8e4c60f..165121d 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -56,9 +56,15 @@ static PyGetSetDef frame_getsetlist[] = { After all, while a typical program may make millions of calls, a call depth of more than 20 or 30 is probably already exceptional unless the program contains run-away recursion. I hope. + + Later, MAXFREELIST was added to bound the # of frames saved on + free_list. Else programs creating lots of cyclic trash involving + frames could provoke free_list into growing without bound. */ static PyFrameObject *free_list = NULL; +static int numfree = 0; /* number of frames currently in free_list */ +#define MAXFREELIST 200 /* max value for numfree */ static void frame_dealloc(PyFrameObject *f) @@ -91,8 +97,13 @@ frame_dealloc(PyFrameObject *f) Py_XDECREF(f->f_exc_type); Py_XDECREF(f->f_exc_value); Py_XDECREF(f->f_exc_traceback); - f->f_back = free_list; - free_list = f; + if (numfree < MAXFREELIST) { + ++numfree; + f->f_back = free_list; + free_list = f; + } + else + PyObject_GC_Del(f); Py_TRASHCAN_SAFE_END(f) } @@ -245,6 +256,8 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, return NULL; } else { + assert(numfree > 0); + --numfree; f = free_list; free_list = free_list->f_back; if (f->ob_size < extras) { @@ -475,5 +488,7 @@ PyFrame_Fini(void) PyFrameObject *f = free_list; free_list = free_list->f_back; PyObject_GC_Del(f); + --numfree; } + assert(numfree == 0); } -- cgit v0.12