GC and finalizers [was: No destructor]

Paul Duffin pduffin at hursley.ibm.com
Fri Aug 25 05:26:35 EDT 2000


Martin von Loewis wrote:
> 
> Paul Duffin <pduffin at hursley.ibm.com> writes:
> 
> > Even if A and B both had finalisers then it could be cleaned up, you
> > just have to be careful and set out various dos and don'ts for
> > finalisers.
> >
> > Can you give an example of finalisers for A and B which would cause
> > problems ?
> 
> Suppose the following scenario:
> 
> class Head:
>   def __del__(self):
>     free_resource(self.next.item)
> 
> class Middle:
>   pass
> 
> class Tail:
>   def __del__(self):
>     pass
> 
> h=Head()
> h.next=Middle()
> h.next.item=obtain_resource()  # returns int, head object is responsible
>                                # for resource
> t=Tail()
> h.next.val=t
> t.next=h
> del h
> del t
> 

A little picture describing the cycle would be useful.

> Now, clean-up of head, middle, and tail could occur in arbitrary order.
> Clean-up proceeds in the following way:
> - __del__ is called
> - the instance dictionay is cleared
> Clearing the instance dictionary will release further objects, which
> thus breaks the cycle.
> 

The clean up sequence would have to be something more like.

	__del__ is called for all objects in the cycle.

	If any objects now have external references then the garbage
	collection is over.

	The instance dictionary of all objects in the cycle is cleared.

	The storage for the object is freed.

> Assume clean-up starts with the middle object. It invokes __del__
> (nothing to do), then clears the instance dictionary. As a result, the
> value of middle.item is gone. Cleanup of head would fail, as it would
> not find self.next.item; the resource would be lost.
> 

h.next.item is obviously a reference to an object so assuming that it
is the only reference to the object when the dict is cleared the
reference will go and the resource object will be freed and should clean
itself up.

Am I right in saying that because Python does not prevent external accesses
to an object that any object could be the cause of a cycle so every __del__
function would have to check that any external objects it was referencing
were still valid, i.e. not just deleted.

Because the instance dictionaries would not be cleared until all __del__
functions had been called then self.next.item exists when Head.__del__ 
is called. It should probably also check that self.next and self.next.item
are valid anyway.



More information about the Python-list mailing list