gc questions

Jeremy Hylton jeremy at zope.com
Thu Jun 19 12:51:19 EDT 2003


On Wed, 2003-06-18 at 20:23, Edward K. Ream wrote:
> Many thanks, Jeremy, for these hints.  Yes, a dictionary speeds things up a
> lot.  dict[o] = o won't work for unhashable objects o, so here is the code I
> use.  It seems reliable and fast:
> 
>     global lastObjectsDict
> 
>     objects = gc.get_objects()
>     newObjects = [o for o in objects if not lastObjectsDict.has_key(id(o))]
> 
>     lastObjectsDict = {}
>     for o in objects:
>         lastObjectsDict[id(o)]=o
> 
>     print "%d new, %d total objects" % (len(newObjects),len(objects))

The dict using id() trick is convenient in practice, but it has some
problems.  It's possible for an address to get re-used, so that two
different objects get the same id() on two different invocations of this
code.  I expect this is pretty likely for objects that are implemented
with their own free lists.  Whether this is a problem or not depends on
what you are trying to do.

By the way, here's some code that Tim originally wrote that keeps track
of change in number of allocation objects.  It's part of the Zope3 test
runner.  It reports on change in net allocations by type.  It sounds
like this may be along the lines of what you are trying to do.

Jeremy


class TrackRefs:
    """Object to track reference counts across test runs."""

    def __init__(self):
        self.type2count = {}
        self.type2all = {}

    def update(self):
        obs = sys.getobjects(0)
        type2count = {}
        type2all = {}
        for o in obs:
            all = sys.getrefcount(o)
            t = type(o)
            if t in type2count:
                type2count[t] += 1
                type2all[t] += all
            else:
                type2count[t] = 1
                type2all[t] = all

        ct = [(type2count[t] - self.type2count.get(t, 0),
               type2all[t] - self.type2all.get(t, 0),
               t)
              for t in type2count.iterkeys()]
        ct.sort()
        ct.reverse()
        for delta1, delta2, t in ct:
            if delta1 or delta2:
                print "%-55s %8d %8d" % (t, delta1, delta2)

        self.type2count = type2count
        self.type2all = type2all







More information about the Python-list mailing list