From: Chris Rebert on
On Tue, Apr 27, 2010 at 2:58 PM, Chris Rebert <clp2(a)rebertia.com> wrote:
> On Tue, Apr 27, 2010 at 2:42 PM, Michal M <mich.mierzwa(a)googlemail.com> wrote:
>> On 27 Kwi, 23:21, Duncan Booth <duncan.bo...(a)invalid.invalid> wrote:
>>> Michal M <mich.mier...(a)googlemail.com> wrote:
>>> > 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.
>
> 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
From: Michal M on
On Apr 28, 12:02 am, Chris Rebert <c...(a)rebertia.com> wrote:
> On Tue, Apr 27, 2010 at 2:58 PM, Chris Rebert <c...(a)rebertia.com> wrote:
> > On Tue, Apr 27, 2010 at 2:42 PM, Michal M <mich.mier...(a)googlemail.com> wrote:
> >> On 27 Kwi, 23:21, Duncan Booth <duncan.bo...(a)invalid.invalid> wrote:
> >>> Michal M <mich.mier...(a)googlemail.com> wrote:
> >>> > 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.
>
> > 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:
> Seehttp://docs.python.org/library/gc.html#gc.garbage
>
> - Chris

Thanks, specially for pointing the last issue with __del__ - I missed
that!
From: Christian Heimes on
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

From: Marius Gedminas on
On Apr 28, 3:59 pm, Christian Heimes <li...(a)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
From: Marius Gedminas on
On Apr 27, 11:45 pm, Michal M <mich.mier...(a)googlemail.com> wrote:
> 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.

--
Marius Gedminas