Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to check what is holding reference to object

11 views
Skip to first unread message

Michal M

unread,
Apr 27, 2010, 4:45:16 PM4/27/10
to
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.

Chris Rebert

unread,
Apr 27, 2010, 5:08:36 PM4/27/10
to Michal M, pytho...@python.org

gc.get_referrers(your_object) ?

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

Cheers,
Chris
--
Thanks for having me learn something new today!
http://blog.rebertia.com

Duncan Booth

unread,
Apr 27, 2010, 5:21:28 PM4/27/10
to
Michal M <mich.m...@googlemail.com> wrote:

See if this code helps:

http://groups.google.com/group/comp.lang.python/browse_thread/thread/394ba5b48f83ebfb/237dc92f3629dd9a#237dc92f3629dd9a

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

Michal M

unread,
Apr 27, 2010, 5:42:44 PM4/27/10
to
On 27 Kwi, 23:21, Duncan Booth <duncan.bo...@invalid.invalid> wrote:

> Michal M <mich.mier...@googlemail.com> wrote:
> > 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.
>
> 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"

>> a = A()
>> del a
A object delted
>> a = A()
>> a.b()
>> del a
... nothing ...

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

Chris Rebert

unread,
Apr 27, 2010, 5:58:48 PM4/27/10
to Michal M, pytho...@python.org

No, it does, you just didn't give it long enough; for performance
reasons, cyclical GC is only done every so often:

>>> from weakref import ref
>>> class A(object):
... def a(self):
... pass
... def b(self):
... self.method = self.a
...
>>> a = A()
>>> def bye(x): print "BYE:", x
...
>>> b = ref(a, bye)
>>> del a
BYE: <weakref at 0x377990; dead>
>>> a = A()
>>> b = ref(a, bye)
>>> a.b()
>>> del a
>>>
>>> #indeed, it didn't get GC-ed immediately
>>> from gc import collect
>>> collect() #but if we force a cyclical GC run...
BYE: <weakref at 0x4441b0; dead>

Cheers,
Chris
--
http://blog.rebertia.com

Chris Rebert

unread,
Apr 27, 2010, 6:02:07 PM4/27/10
to Michal M, pytho...@python.org
On Tue, Apr 27, 2010 at 2:58 PM, Chris Rebert <cl...@rebertia.com> wrote:
> On Tue, Apr 27, 2010 at 2:42 PM, Michal M <mich.m...@googlemail.com> wrote:
> No, it does, you just didn't give it long enough; for performance
> reasons, cyclical GC is only done every so often:

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

- Chris

Michal M

unread,
Apr 28, 2010, 3:01:05 AM4/28/10
to
On Apr 28, 12:02 am, Chris Rebert <c...@rebertia.com> wrote:
> On Tue, Apr 27, 2010 at 2:58 PM, Chris Rebert <c...@rebertia.com> wrote:

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

Christian Heimes

unread,
Apr 28, 2010, 8:59:42 AM4/28/10
to pytho...@python.org
Almar Klein wrote:
> Ah, it does exist! I wish I knew that two months ago, it would've saved me
> some precious time ;)

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. IIRC all types written in
Python are gc-aware.

Christian

Marius Gedminas

unread,
May 5, 2010, 3:46:25 PM5/5/10
to
On Apr 28, 3:59 pm, Christian Heimes <li...@cheimes.de> wrote:
> 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

>>> import gc
>>> gc.get_referrers(42)

?


Marius Gedminas

Marius Gedminas

unread,
May 5, 2010, 3:47:35 PM5/5/10
to

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

--
Marius Gedminas

0 new messages