[gclist] Finalization and death notices

Kerns, Bob Bob.Kerns@firepond.com
Mon, 8 Oct 2001 11:16:42 -0500


The drawback to all this, compared to death notices, is that presence on the
queue extends the object's lifetime.

A buggy mutator that forgot to close the file stream not only leaves open
the file descriptor -- it also leaves allocated the buffer storage, index
B-Tree, pool of connection objects, and other things associated with the
file.

I know, I padded this list beyond a bare buffered file stream; the point is,
this is an unbounded amount of storage to hang onto, just to enable a final
cleanup on the file descriptor!

I like true death noticies, instead of these "near death notices", because
they focus on the real requirements.

-----Original Message-----
From: Nick Barnes [mailto:Nick.Barnes@pobox.com]
Sent: Monday, October 08, 2001 4:27 AM
To: gclist@iecc.com
Subject: Re: [gclist] Finalization and death notices 


All this talk about finalization prompts me to describe the
finalization system we have in our Memory Pool System (MPS).  Here it
is:

  The mutator may register an object for finalization.  It may
  register the same object for finalization more than once (as if
  incrementing a counter).
  
  When the MPS observes that an object registered for finalization
  would otherwise be reclaimable, it deregisters it for finalization
  (as if decrementing the counter) and adds a finalization message,
  containing a reference to the object, to its message queue.
  
  The message queue may be read by the mutator, at the mutator's
  convenience.  Messages must be explicitly destroyed by the mutator.

Notes:

(1) The object remains alive until (at least) such time as the mutator
destroys the finalization message.  The mutator is free to do what it
likes with the object, including create new references to it and
re-registering it for finalization.

(2) Finalizers (if any) get run by the mutator, synchronously with the
mutator's other activity, at the mutator's convenience.  They are not
run by the MPS.  Any problems with locking, threads, and object
ownership are up to the mutator to resolve (as usual).  It is simple
for the mutator to run finalizers by module (by adding another queue,
with filtering by module, on the mutator side).

(3) Finalization ends when a finalization message is enqueued.  As far
as the MPS is concerned, any "finalizer" is just another part of the
mutator.

(4) Ensuring that finalizers are run eventually is a problem for the
mutator.  If the mutator doesn't read the queue, or doesn't run the
finalizers, or takes an early bath with messages still on the queue,
that is the mutator's problem.

We don't use liveness terminology in this context, because the object
in question is certainly _not_ dead.  How can it be dead when I have a
pointer to it right here?  Talk about liveness in the context of
finalization leads to all sort of semantic nonsense like "resurrection
of the dead".  The mutator has simply asked the GC to do it a favour
by using the GC's uniquely global knowledge of object reachability to
let it know when an object is not _otherwise_ reachable.

Nick Barnes
Ravenbrook Limited