<> <> = Reference Cycles = How to find and eliminate reference cycles in Mercurial's data structures. Mercurial produces reference cycles that need to be broken up by the gc to clean up unused objects. This is relevant if Mercurial is to be used via its Python API in a server application implemented in Python. Snippet 1 {{{ import os, sys import gc from pprint import pprint gc.set_debug(gc.DEBUG_LEAK) class propertycache(object): def __init__(self, func): self.func = func self.name = func.__name__ def __get__(self, obj, type=None): result = self.func(obj) setattr(obj, self.name, result) return result class a(object): def __init__(self): self.dict = {} def f(self): return len(self.dict) @propertycache def g(self): return self.f b = a() print b.g, b.g() b = None print "gc.collect() returns %s" % gc.collect() pprint(gc.garbage) }}} Produces (Python 2.5.1 on Windows): {{{ > python test.py > 0 gc: collectable gc: collectable gc: collectable gc: collectable gc.collect() returns 4 [<__main__.a object at 0x00A9B930>, {}, {'dict': {}, 'g': >}, >] }}} Snippet 2 {{{ from mercurial import hg, ui, util import os import gc def test(): print "Mercurial version: %s" % util.version() repo = hg.repository(ui.ui(), os.getcwd()) status = repo.status() print status test() print "gc.collect() returns %s" % gc.collect() }}} gives: {{{ > python test2.py Mercurial version: 6f21613d25a2 ([], [], [], [], [], [], []) gc.collect() returns 152 }}} {{{gc.collect}}} returns the number of unreachable objects found (152 in this case). === See also === * http://docs.python.org/library/gc.html * http://idisk.mac.com/danchr-Public/cycles.png * http://paste.lisp.org/display/81379 * http://selenic.com/repo/index.cgi/hg/rev/3507f6c7715c - dirstate: eliminate reference cycle from normalize ---- CategoryDeveloper