GC and finalizers [was: No destructor]

Martin von Loewis loewis at informatik.hu-berlin.de
Tue Sep 5 17:57:05 CEST 2000


Paul Duffin <pduffin at hursley.ibm.com> writes:

> So how are these "unbreakable" cycles supposed to be prevented, the only
> way that I can see is to remove finalizers from classes which may find
> themselves in a cycle. The trouble with this is that the finalizers are
> there for a purpose and it may not be possible to remove them. 
> 
> What can be done in this situation to prevent "unbreakable" cycles ?

It is always possible to re-organize a program so it won't have
instances that both have a finalizer and participate in a cycle.

To participate in a cycle, an instance attribute must point to the
next object in the cycle. Suppose we have a class A

class A:
  def __init__(self,cyclic,resource):
    self.cyclic = cyclic
    self.resource = resource

  def __del__(self):
    release_resource(self.resource)

where the cyclic attribute may be part of a cycle. That can be changed to

class ResourceHolder:
  def __init__(self,resource):
    self.resource = resource

  def __del__(self):
    release_resource(self.resource)

class A:
  def __init__(self,cyclic,resource):
    self.cyclic = cyclic
    self.resource = ResourceHolder(resource)

So if A instances get into the cycle, then gc would collect them,
i.e. clear their __dict__. As a result, the ref count on self.resource
would drop to zero, and __del__ of the ResourceHolder would be invoked
(as another result, it would als decref self.cyclic, which results in
releasing the memory occupied by the cycle).

Regards,
Martin



More information about the Python-list mailing list