[PEAK] Re: [TransWarp] releasing component subtrees

Phillip J. Eby pje at telecommunity.com
Tue Oct 21 11:45:48 EDT 2003

At 04:56 PM 10/21/03 +0300, alexander smishlajev wrote:
>is there a simple and safe way to release subtrees in the component hierarchy?
>our application from time to time is runnung tasks that should die after 
>doing their job.  but my colleague found that the dead tasks remain in 
>memory because of circular references between parent and child components 
>that are not detected by python gc.

Python doesn't do GC on objects that have __del__ methods.  If you get rid 
of the __del__ method in your example, the GC should run.  Alternatively, 
if you leave the __del__ in, and run gc.collect(), you'll probably find 
your tasks end up in gc.garbage.

So, if you don't really need __del__, don't use it.  In particular, having 
a component class use __del__ is a bad idea, because components nearly 
always involve circular references (parent->child and child->parent).

In general, __del__ is used to release resources, so the best place to put 
the __del__ is on the resources themselves, assuming that the resources are 
not part of a circular structure.  (If you look at peak.storage.DDE, 
there's a class called ServerManager with a __del__ that does this.)

By the way, all of this is a general Python GC issue; nothing specifically 
to do with PEAK here, except the fact that if you have a component, it's 
going to reference its parent.

>   these cycles may be broken by wrapping each binding into weakref, but 
> this would be a remarkable additional work.

There's an easier way, at least for your example.  Declare your 'task1' and 
'task2' bindings as 'noCache=True'.  Then, the parent that creates them 
doesn't keep references to them. (Although they will keep references to it 
until their refcount goes to zero, which will happen when they stop, and 
are not in the task queue nor scheduled to return to the queue.)

This approach should work even if you leave __del__ in place.

>below is a simple example.  it creates a task with two subtasks.  each of 
>these tasks terminates as soon as it is run.  no reference is kept to the 
>container task,

Not true; every component has a reference to its parent; that's how they 
find their parents.

More information about the PEAK mailing list