On Jan 19, 10:31 pm, Christian Heimes <[EMAIL PROTECTED]> wrote: > Jeroen Ruigrok van der Werven wrote: > > > Hi Christian, > > > -On [20080119 16:16], Christian Heimes ([EMAIL PROTECTED]) wrote: > >> I forgot one important point in my reply. The GC module contains some > >> useful methods for debugging. Check gc.garbage. It should be empty. > > > Yeah, we're messing around with that stuff as well as many other ways of > > trying to track issues, but it can really be looking for a needle in a > > haystack to be honest. > > There's so much output that, I guess, make sense only when you're semi-deep > > into the Python internals to even make heads or tails out of it. =\ > > And even third-party code is not helping much to reduce the clutter and > > provide insight. > > Under normal circumstances gc.garbage should be an empty list. In > general it's a bad sign if gc.garbage contains lots of objects. > > I found several potential leaks in trac: > > $ find -name \*.py | xargs grep __del__ > ./trac/versioncontrol/svn_fs.py: def __del__(self): > ./trac/versioncontrol/svn_fs.py: def __del__(self): > ./trac/db/pool.py: def __del__(self): > > $ find -name \*.py | xargs grep frame > ./trac/web/main.py: > [...] > ./trac/core.py: frame = sys._getframe(1) > ./trac/core.py: locals_ = frame.f_locals > > I recommend that you either replace __del__ with a weak reference > callback or to remove it. Referencing a frame, traceback or f_locals is > going to leak, too. You *must* explicitly del every frame and locals > variable. > > Christian
many thanks! as the main change was replacing clearsilver with genshi, this means one could do the same thing with genshi, http://genshi.edgewall.org/? $ find -name \*.py | xargs grep frame ./genshi/filters/html.py: 'dir', 'disabled', 'enctype', 'for', 'frame', 'headers', 'height', ./genshi/input.py: _EMPTY_ELEMS = frozenset(['area', 'base', 'basefont', 'br', 'col', 'frame', ./genshi/output.py: 'http://www.w3.org/TR/html4/frameset.dtd' ./genshi/output.py: 'http://www.w3.org/TR/xhtml1/DTD/xhtml1- frameset.dtd' ./genshi/output.py: * "html-transitional" for the HTML 4.01 frameset DTD ./genshi/output.py: * "xhtml-frameset" for the XHTML 1.0 frameset DTD ./genshi/output.py: 'html-frameset': DocType.HTML_FRAMESET, ./genshi/output.py: 'xhtml-frameset': cls.XHTML_FRAMESET, ./genshi/output.py: _EMPTY_ELEMS = frozenset(['area', 'base', 'basefont', 'br', 'col', 'frame', ./genshi/template/base.py: _ctxt2dict = lambda ctxt: ctxt.frames[0] ./genshi/template/base.py: self.frames = deque([data]) ./genshi/template/base.py: self.pop = self.frames.popleft ./genshi/template/base.py: self.push = self.frames.appendleft ./genshi/template/base.py: return repr(list(self.frames)) ./genshi/template/base.py: for frame in self.frames: ./genshi/template/base.py: if key in frame: ./genshi/template/base.py: del frame[key] ./genshi/template/base.py: value, frame = self._find(key) ./genshi/template/base.py: if frame is None: ./genshi/template/base.py: self.frames[0][key] = value ./genshi/template/base.py: """Retrieve a given variable's value and the frame it was found in. ./genshi/template/base.py: for frame in self.frames: ./genshi/template/base.py: if key in frame: ./genshi/template/base.py: return frame[key], frame ./genshi/template/base.py: for frame in self.frames: ./genshi/template/base.py: if key in frame: ./genshi/template/base.py: return frame[key] ./genshi/template/base.py: for frame in self.frames: ./genshi/template/base.py: keys += [key for key in frame if key not in keys] ./genshi/template/directives.py: # Store the function reference in the bottom context frame so that it ./genshi/template/directives.py: ctxt.frames[-1][self.name] = function ./genshi/template/directives.py: frame = {} ./genshi/template/directives.py: ctxt.push(frame) ./genshi/template/tests/directives.py: frame = exc_traceback.tb_next ./genshi/template/tests/directives.py: frames = [] ./genshi/template/tests/directives.py: while frame.tb_next: ./genshi/template/tests/directives.py: frame = frame.tb_next ./genshi/template/tests/directives.py: frames.append(frame) ./genshi/template/tests/directives.py: frames[-1].tb_frame.f_code.co_name) ./genshi/template/tests/directives.py: frames[-1].tb_frame.f_code.co_filename) ./genshi/template/tests/directives.py: self.assertEqual(2, frames[-1].tb_lineno) ./genshi/template/tests/eval.py: frame = exc_traceback.tb_next ./genshi/template/tests/eval.py: frames = [] ./genshi/template/tests/eval.py: while frame.tb_next: ./genshi/template/tests/eval.py: frame = frame.tb_next ./genshi/template/tests/eval.py: frames.append(frame) ./genshi/template/tests/eval.py: frames[-3].tb_frame.f_code.co_name) ./genshi/template/tests/eval.py: frames[-3].tb_frame.f_code.co_filename) ./genshi/template/tests/eval.py: self.assertEqual(50, frames[-3].tb_lineno) ./genshi/template/tests/eval.py: frame = exc_traceback.tb_next ./genshi/template/tests/eval.py: while frame.tb_next: ./genshi/template/tests/eval.py: frame = frame.tb_next ./genshi/template/tests/eval.py: code = frame.tb_frame.f_code ./genshi/template/tests/eval.py: self.fail("never found the frame I was looking for") ./genshi/template/tests/eval.py: self.assertEqual(50, frame.tb_lineno) ./genshi/template/tests/eval.py: frame = exc_traceback.tb_next ./genshi/template/tests/eval.py: while frame.tb_next: ./genshi/template/tests/eval.py: frame = frame.tb_next ./genshi/template/tests/eval.py: code = frame.tb_frame.f_code ./genshi/template/tests/eval.py: self.fail("never found the frame I was looking for") ./genshi/template/tests/eval.py: self.assertEqual(50, frame.tb_lineno) rupert -- http://mail.python.org/mailman/listinfo/python-list