[gclist] Finalizer flame wars.

Hans Boehm boehm@hoh.mti.sgi.com
Fri, 10 May 1996 16:03:49 -0700


Charles wrote:
"For example suppose finalizers
are used to free file handles. If the process is slow enough your program
will crash when it can't get a file handle. You will have an intrmittent
bug, it will doubtless occur on a users system at the maxamally inconvienient
time (when he has lots of data) and be impossable to reproduce."

Your program will crash only if your collector still considers all file handles
to be accessible.  Otherwise it can garbage collect repeatedly until no more
finalizers can be run or file handles become available.  If that fails, you
will get a message saying that you ran out of file handles.  If I need to
reproduce the problem, I can probably reproduce it by decreasing the number of
available handles.  It's quite possible to write a tool that identifies why the
handles are retained.

"Garbage collection should a tool suitable for mission critical programming.
Mission critical means "If it fails something unacceptable happens like an
aircraft becoming a post hole digger." Clearly collector based finalizers are
not useful in this context. So as a language designer I will do finalizers
in some other way. Having them lay around the garbage collector then becomes
a waste of time, a source of unnessisary complexity and an invitation to
disaster. Collector delays are a source of trouble already, collector based
finalizers make it worse even if they are an unused feature."

I think we're confusing issues here.  The applications I write are not safety
critical.  If I had to write a safety critical application, I would trust none
of:

1. A conservative garbage collector.
2. Any other garbage collector I know of.
3. Any malloc/free implementation I know of.
4. A C++ compiler or its output.  (I might trust a C compiler after manually
checking its output, and verifying that in addition to being correct, it met
required resource constraints.  At least at present, I usually have too much
trouble reading C++ compiler output.)

I'm not sure what "mission critical" means.  I do know that GC-triggered
finalizers allow me to solve problems easily that otherwise don't get solved.
 The "cord" implementation that comes with my collector sometimes relies on
finalization to manage file handles.  As a result, it becomes easy to implement
a "file to cord" conversion function that reads lazily, and the little demo
editor can handle files larger than swap space.  Very few real editors bother
to implement this because it's otherwise hard.  As a result, my toy has
actually been used occasionally to view files that the "industrial strength"
editors can't handle.  (Don't use it to edit files, though.  Older versions
have a serious bug writing files back.)

Could this have been done with separate reference-count-based finalizers?  Yes.
 But cords themselves, and all objects that reference cords would also have to
be reference counted.  Thus the garbage collector would be essentially useless.
 And file access would have been much slower (see
ftp://parcftp.xerox.com/pub/gc/example.html).

Does it introduce a file handle leak?  In the case of the toy editor, no.  It
opens at most one such file, which it needs until exit.  In general, it could
leak handles to files that have become embedded in strings temporarily.  But I
can't think of a realistic case in which this would matter with probability
anywhere near that of a power failure.

Hans