Differences between revisions 3 and 7 (spanning 4 versions)
Revision 3 as of 2009-06-07 10:18:22
Size: 2014
Editor: abuehl
Comment:
Revision 7 as of 2012-10-25 21:34:18
Size: 2298
Editor: mpm
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
<<Include(A:dev)>>
<<Include(A:style)>>

= Reference Cycles =

How to find and eliminate reference cycles in Mercurial's data structures.
Line 86: Line 93:
 * http://selenic.com/repo/index.cgi/hg/rev/3507f6c7715c - dirstate: eliminate reference cycle from normalize

----
CategoryDeveloper

Note:

This page is primarily intended for developers of Mercurial.

{i} This page does not meet our wiki style guidelines. Please help improve this page by cleaning up its formatting.

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
<bound method a.f of <__main__.a object at 0x00A9B930>> 0
gc: collectable <a 00A9B930>
gc: collectable <dict 00A99150>
gc: collectable <dict 00A99270>
gc: collectable <instancemethod 00A90AA8>
gc.collect() returns 4
[<__main__.a object at 0x00A9B930>,
 {},
 {'dict': {}, 'g': <bound method a.f of <__main__.a object at 0x00A9B930>>},
 <bound method a.f of <__main__.a object at 0x00A9B930>>]

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


CategoryDeveloper

ReferenceCycles (last edited 2012-10-25 21:34:18 by mpm)