Reference Counts

Tim Peters tim.peters at gmail.com
Fri May 19 11:59:22 EDT 2006


[raghu, on Heiko Wundram's test program:

import sys

x = {}
i = 0
def test():
   global x, i
   x[i] = "test"
   i += 1
   del x[i-1] # Properly clean up x.

for j in xrange(10000):
   print "Before", j, ":", sys.gettotalrefcount()
   test()
   print "After", j, ":", sys.gettotalrefcount()
]

> Hmm...
>
> I tried the gc.collect(). It aint helping. The reference count still
> keeps growing till 5 after it which it drops. As you said, it is not
> gonna hurt right away.
>
> The only downside in that mysterious up and down thingie is that , we
> could get to a wrong conclusion about a leak, if we ran the algo for
> say 3 times. Right ?
>
> Thanks Heiko for all the help. And in case, you get to decode the
> mystery behind the increase before the decrease ..kindly let me know.

It has nothing to do with cyclic gc.  It has to do with this:

   del x[i-1] # Properly clean up x.

When you remove a dictionary key, under the covers the dictionary slot
that contained the deleted <key, value> pair has its value portion set
to a special "dummy" object.  This is invisible from the Python level
(there's no way you can get at this object), but the dummy object is a
real Python object, and like all Python objects has a refcount.  Each
time the dummy object gets used, its refcount is bumped, and that
shows up in gettotalrefcount().  From time to time the dict resizes,
and then the number of references to the dummy dict value changes
sharply.

Except in the upcoming 2.5 release.  The refcount on the dummy dict
value (and the similar dummy set value) confuses people so much that
gettotalrefcount() has been changed in 2.5 to subtract the refcounts
on the dummy dict and set values.  As a result, running under current
2.5 trunk Heiko's program is steady as a rock:

Before 0 : 25632
After 0 : 25632
Before 1 : 25632
After 1 : 25632
Before 2 : 25632
After 2 : 25632
Before 3 : 25632
After 3 : 25632
Before 4 : 25632
After 4 : 25632
Before 5 : 25632
After 5 : 25632
Before 6 : 25632
After 6 : 25632
Before 7 : 25632
After 7 : 25632
Before 8 : 25632
After 8 : 25632
Before 9 : 25632
After 9 : 25632
Before 10 : 25632
After 10 : 25632
...



More information about the Python-list mailing list