How to check what is holding reference to object

M

Michal M

Hi

I've just found out that one of objects is not destroyed when it
should be. This means that something was holding reference to this
object or part of it (i.e. method). Is there any way to check what
holds that reference? I am unable to do that just looking to the code
or debugging it because it is pretty complicated, but I am able to
invoke this situation again.

Regards
Michal M.
 
C

Chris Rebert

I've just found out that one of objects is not destroyed when it
should be. This means that something was holding reference to this
object or part of it (i.e. method). Is there any way to check what
holds that reference? I am unable to do that just looking to the code
or debugging it because it is pretty complicated, but I am able to
invoke this situation again.

gc.get_referrers(your_object) ?

Docs: http://docs.python.org/library/gc.html#gc.get_referrers

Cheers,
Chris
 
M

Michal M

See if this code helps:

http://groups.google.com/group/comp.lang.python/browse_thread/thread/...

It's pretty old so it may need some adjustment, but I wrote it
to figure out exactly that sort of problem.

Thanks you for answers.
I tried to use gc.get_referrers(self) in point in code when according
to me object should be destroyed earlier but I did not see anything
interesting. Then just realised that gc will not destroy object even
when itself holds reference to his own method.

For example

class A(object):
def a(self):
pass
def b(self):
self.method = self.a
def __del__(self):
print "A object deleted"
.... nothing ...

I thought gc would discover such circle loops but apparently it did
not.
 
C

Chris Rebert

Thanks you for answers.
I tried to use gc.get_referrers(self) in point in code when according
to me object should be destroyed earlier but I did not see anything
interesting. Then just realised that gc will not destroy object even
when itself holds reference to his own method.

For example

class A(object):
 def a(self):
   pass
 def b(self):
   self.method = self.a
 def __del__(self):
   print "A object deleted"

... nothing ...

I thought gc would discover such circle loops but apparently it did
not.

No, it does, you just didn't give it long enough; for performance
reasons, cyclical GC is only done every so often:
.... def a(self):
.... pass
.... def b(self):
.... self.method = self.a
....BYE: <weakref at 0x4441b0; dead>

Cheers,
Chris
 
M

Michal M

Addendum:
Also, defining __del__ in your example was likely problematic:
Seehttp://docs.python.org/library/gc.html#gc.garbage

- Chris

Thanks, specially for pointing the last issue with __del__ - I missed
that!
 
M

Marius Gedminas

The trick works only for objects that are tracked by CPython's garbage
collector. Simple and non-containerish objects like str, int, unicode
and some other types aren't tracked by the gc.

Yes they are -- have you ever tried

?


Marius Gedminas
 
M

Marius Gedminas

I've just found out that one of objects is not destroyed when it
should be. This means that something was holding reference to this
object or part of it (i.e. method). Is there any way to check what
holds that reference? I am unable to do that just looking to the code
or debugging it because it is pretty complicated, but I am able to
invoke this situation again.

I wrote http://pypi.python.org/pypi/objgraph for this purpose.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,823
Latest member
Nadia88

Latest Threads

Top