473,782 Members | 2,487 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Reference Counts

Hi All,

I am a new user of Python and am having a bit of problem understanding
the Reference counting and memory leakage issues.

Requesting help from experienced users....

I wrote the following simple program.
#!/usr/bin/python

import sys
global a

print "Total Reference count at the start =",sys.gettotal refcount()
a=1
print "a ref count =",sys.getrefco unt(a)
b=a
print "a ref count =",sys.getrefco unt(a)

del a
del b

print "Total Reference count at the end =",sys.gettotal refcount()
I executed it. I am seeing the following.

Total Reference count at the start = 16538
a ref count = 49
a ref count = 50
Total Reference count at the end = 16540
[6416 refs]

There are a few questions that I am having on this.

(1) Why should 'a' reference count be 49 before I even made an
assignment ?
(2) The Total Reference count at the end has increased by 2 . Why ? Am
I leaking memory ?
(3) I have read somewhere that an increase in sys.gettotalref count() is
indicative of a memory leak ? Aint that correct ?

Thanks for the help.

Bye,
raghavan V

May 18 '06 #1
5 1430
Am Donnerstag 18 Mai 2006 08:28 schrieb raghu:
#!/usr/bin/python

import sys
global a

print "Total Reference count at the start =",sys.gettotal refcount()
a=1
print "a ref count =",sys.getrefco unt(a)
b=a
print "a ref count =",sys.getrefco unt(a)

del a
del b

print "Total Reference count at the end =",sys.gettotal refcount()
...
Total Reference count at the start = 16538
a ref count = 49
a ref count = 50
Total Reference count at the end = 16540
[6416 refs]

There are a few questions that I am having on this.

(1) Why should 'a' reference count be 49 before I even made an
assignment ?
Because "1" is a special integer. Small integers (-1..100, but this depends on
the Python version) are interned, similar to strings, so there are already
references to the integer object before you assign it to "a" (at least one; 1
is such a "magic" constant that you can guess that there are already other
references to it in other places of the stdlib, which has loaded when your
script runs, so it's not hard to imagine that 1 already has 48 references
outside of your program).
(2) The Total Reference count at the end has increased by 2 . Why ? Am
I leaking memory ?
No. I'd guess that the names "a" and "b" were interned as strings (as they are
used as dict lookup keys in the globals() dict), and you have one reference
to each interned object.
(3) I have read somewhere that an increase in sys.gettotalref count() is
indicative of a memory leak ? Aint that correct ?


Yes. It is correct if consecutive runs of your algorithm always yield a higher
sys.gettotalref count() for each run. In this case (where you run
your "algorithm" only once), it isn't. It just shows you some of the innards
of the Python runtime machinery.

Execute the following script to see the result of a memory leak:
import sys

x = {}
i = 0
def test():
global x, i
x[i] = "test"
i += 1
# Forget to clean up x... LEAK a reference to "test"!

for j in xrange(10000):
print "Before", j, ":", sys.gettotalref count()
test()
print "After", j, ":", sys.gettotalref count()
And, the following (slightly altered) program doesn't exhibit this memory
leak:
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.gettotalref count()
test()
print "After", j, ":", sys.gettotalref count()


I don't have a debug build of Python at hand, so I can't run them now. But, if
you're interested in the results, you'll certainly do that yourself. ;-)

--- Heiko.
May 18 '06 #2
Heiko,

Thanks for the explanation. I understood the idea of 1 being interned.
Also I understood the globals vars having a reference in the internal
dict.

I ran the "leaky" version of the program and yes...it showed a
progressively increasing totalrefcount as below.
Before 0 : 16579
After 0 : 16581
Before 1 : 16581
After 1 : 16583
Before 2 : 16583
After 2 : 16585
Before 3 : 16585
After 3 : 16587
Before 4 : 16587
After 4 : 16589
Before 5 : 16589
After 5 : 16591
Before 6 : 16591
After 6 : 16593
Before 7 : 16593
After 7 : 16595
Before 8 : 16595
After 8 : 16597
Before 9 : 16597
After 9 : 16599
Before 10 : 16599
After 10 : 16601
Before 11 : 16601
After 11 : 16603
Before 12 : 16603
After 12 : 16605
Before 13 : 16605
After 13 : 16607
Before 14 : 16607
After 14 : 16609
Before 15 : 16609

However, the 'non-leaky' one showed a funny trend ...it kept increasing
the totalrefcount for five iterations (see 1 thru 5) and then dropped
down by 5 ( See Before 5 : 16584
After 5 : 16580 ) suddenly and again increase as shown below. However,
at the time when the script finsished execution, we were not too far
from the starting totalrefcount (16584 from 16579),
Before 0 : 16579
After 0 : 16580
Before 1 : 16580
After 1 : 16581
Before 2 : 16581
After 2 : 16582
Before 3 : 16582
After 3 : 16583
Before 4 : 16583
After 4 : 16584
Before 5 : 16584
After 5 : 16580
Before 6 : 16580
After 6 : 16581
Before 7 : 16581
After 7 : 16582
Before 8 : 16582
After 8 : 16583
Before 9 : 16583
After 9 : 16584
Before 10 : 16584
After 10 : 16580
Before 11 : 16580
After 11 : 16581
Before 12 : 16581
After 12 : 16582
Before 13 : 16582
After 13 : 16583
Before 14 : 16583
After 14 : 16584
Before 15 : 16584

What is the Mystery behind the increase and the subsequent drop ?

Thanks.

Raghavan V

May 18 '06 #3
Am Donnerstag 18 Mai 2006 09:33 schrieb raghu:
However, the 'non-leaky' one showed a funny trend ...it kept increasing
the totalrefcount for five iterations (see 1 thru 5) and then dropped
down by 5 ( See Before 5 : 16584
After 5 : 16580 ) suddenly and again increase as shown below. However,
at the time when the script finsished execution, we were not too far
from the starting totalrefcount (16584 from 16579),


The cyclic garbage collector isn't run after every byte-code instruction, but
only after several have executed (because of performance issues). That's why
you see an increase in reference counts, until the interpreter calls the
garbage collector, which frees the object cycles, and so forth. I don't
exactly know what the "magic constant" (i.E. number of byte-code instructions
between subsequent runs of the garbage collector) is, but I presume it's
somewhere in the order of 100 bytecode instructions.

Why you need the cyclic gc to clean up the data structures my sample creates
is beyond be, but I'd guess it has something to do with the internal
structure of dicts.

Anyway, you can easily test this hypothesis by calling

gc.collect()

explicitly in the main loop after test() has run (remember to import
gc... ;-)). This forces a run of the cyclic gc. If funny pattern still
remains I wouldn't know of any other explanation... ;-) But, as long as
references aren't being leaked (you don't see the drop in references after
every x instructions), there's nothing to worry about.

--- Heiko.
May 18 '06 #4
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.

Bye,
Raghavan V

May 19 '06 #5
[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.gettotalref count()
test()
print "After", j, ":", sys.gettotalref count()
]
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 gettotalrefcoun t(). 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
gettotalrefcoun t() 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
....
May 19 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
4878
by: Eric | last post by:
Hi, After reading the JNI specs, it looks like no JNI call is available to retrieve the reference count for a specific Java Object (LocalRef or GlobalRef). I would like to able to retrieve the "reference count", is it possible? Without using JVMPI or JVMDI ... Thanks
6
2185
by: Elbert Lev | last post by:
Please correct me if I'm wrong. Python (as I understand) uses reference counting to determine when to delete the object. As soon as the object goes out of the scope it is deleted. Python does not use garbage collection (as Java does). So if the script runs a loop: for i in range(100): f = Obj(i)
6
2257
by: Chris S. | last post by:
I'm trying to make a graphical editor and browser for Pickled files. One aspect I'm not sure about is how to detect multiple references to the same data. For instance, say I had the Pickled data: a= b= c= d=
1
3256
by: Tony Johansson | last post by:
Hello Experts! I reading a book called programming with design pattern revealed by Tomasz Muldner and here I read something that I don't understand completely. It says "A garbarage collector, such as the one used in Java, maintains a record of whether or not an object is currentlys being used. An unused object is tagged as garbage,
4
3409
by: z_learning_tester | last post by:
I'm reading the MS press C# book and there seems to be a contradiction. Please tell me which one is correct, 1 or 2. Thanks! Jeff 1. First it gives the code below saying that it prints 0 then 42. They say that 42 is printed the second time since the value was wrapped in a class and therefore became passed by reference. (sorry for any typos I am a newbie here ;-)
4
4198
by: aaronfude | last post by:
Hi, Please consider the following class (it's not really my class, but it's a good example for my question): class Vector { int myN; double *myX; Vector(int n) : myN(n), myX(new double) { } double &operator()(int i) { return myX; }
1
2509
by: DaveO. | last post by:
Hello, I'm calling a VB.NET web service, also from VB.NET, and I get the error " Object reference not set to an instance of an object" on the following line in Reference.vb, when it tries to make the call: Dim results() As Object = Me.Invoke("Phys_Post", New Object() {SessionID, a, b, c, d, CountList}) I can call other web services I've written just fine. This one is more
1
2278
by: oec.deepak | last post by:
Hi Cn any one telll me what is Reference counting in C++.
68
4653
by: Jim Langston | last post by:
I remember there was a thread a while back that was talking about using the return value of a function as a reference where I had thought the reference would become invalidated because it was a temporary but it was stated that it would not. This has come up in an irc channel but I can not find the original thread, nor can I get any code to work. Foo& Bar( int Val ) { return Foo( Val ); }
0
9639
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9479
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10146
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9942
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8967
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6733
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5378
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5509
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3639
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.