[gclist] Buffy finalizer slayer.

David Chase chase@world.std.com
Tue, 15 Jun 1999 14:02:24 -0400

At 07:12 AM 6/15/99 -0500, Charles Fiterman wrote:
>Finalizers corrupt the semantics of a language the way vampires would
>corrupt the structure of physics.

Yes, but.  Nasty practical constraints have corrupted the semantics
of our programming languages in numerous other ways, and we (generally)
cope pretty well.  For instance, our "integers" are actually one of
two interpretations of a finite ring.  Our "floating point numbers"
are only an approximation of the real line.  The problem with finalization
is that people seemingly have the most amazing expectations for what
it might do for them.  I agree that the sort of finalization micromanagement
that you propose is appealing, but it is more expensive in the garbage
collector, not less, and I think it is at least as prone to programmer
error.  (Sorry if my view of programmer skills is especially low, but
that's what experience teaches me.  Note that I am a programmer too.)

>In most cases order shouldn't matter exactly as Java says.

I think that Java called it about right; by being explicit in
the spec about:

1. it runs only once per object
2. in no particular order
3. eventually, maybe

people are given a clear indication that this is a limited tool,
and not to get too ambitious about what it will do for you.
The only problem is that so many people using computer languages
do not read the spec, or are not able to comprehend it, or do
not believe it, or do not care.

In addition, they added the feature(s) that you want to 1.2,
in the form of PhantomReferences.  You end up building very
screwy data structures, but such is life.  A typical screwy
data structure looks like:

  TheType {
    MyPhantomReference allMyData;
    // delegate all methods to allMyData
    static ReferenceQueue unreachable = new ...;
    TheType() {
	allMyData = new MyPhantomReference(this, unreachable);

At least, I think I have that right.  This is far from
free; the delegation takes time, the extra object takes
space.  Ordinary finalizers are cheaper.

>Where it does matter the order should be trivial, buffers before files.

This example doesn't support your position.  If you follow the rule
that f-reachable storage is still reclaimable (see Java) then the
buffer will hang around until the file's finalizer has run.  This
is true whether the buffer has a finalizer or not, though generally
they do not.

David Chase