[Python-Dev] Re: DEBUG_SAVEALL feature for gc not in 2.0b1?

Neil Schemenauer nascheme@enme.ucalgary.ca
Sat, 2 Sep 2000 08:08:48 -0600

On Fri, Sep 01, 2000 at 09:03:51PM -0500, Skip Montanaro wrote:
> What's the difference between "found garbage" and "uncollectable garbage"?

I use the term uncollectable garbage for objects that the collector
cannot call tp_clear on because of __del__ methods.  These objects are
added to gc.garbage (actually, just the instances).  If SAVEALL is
enabled then all objects found are saved in gc.garbage and tp_clear is
not called.

Here is an example of how to use my proposed handle_garbage hook:

	class Vertex:
		def __init__(self):
			self.edges = []
		def add_edge(self, e):
		def __del__(self):

	class Edge:
		def __init__(self, vertex_in, vertex_out):
			self.vertex_in = vertex_in
			self.vertex_out = vertex_out
This graph structure contains cycles and will not be collected by
reference counting.  It is also "uncollectable" because it contains a
finalizer on a strongly connected component (ie. other objects in the
cycle are reachable from the __del__ method).  With the current garbage
collector, instances of Edge and Vertex will appear in gc.garbage when
found to be unreachable by the rest of Python.  The application could
then periodicly do:

	for obj in gc.garbage:
		if isinstance(obj, Vertex):

which would break the reference cycles.  If a handle_garbage hook
existed the application could do:

	def break_graph_cycle(obj, next=gc.handle_garbage):
		if isinstance(obj, Vertex):
			return 1
			return next(obj)
	gc.handle_garbage = break_graph_cycle

If you had a leaking program you could use this hook to debug it:

	def debug_cycle(obj, next=gc.handle_garbage):
		print "garbage:", repr(obj)
		return gc.handle_garbage

The hook seems to be more general than the gc.garbage list.



> What sort of garbage are you appending to gc.garbage now?  I thought by the
> very nature of your garbage collector, anything it could free was otherwise
> "uncollectable".
> S