Thu, 10 Apr 1997 15:29:44 -0500
> There are 2 disadvantages in letting the programm choose the finalization
> 1) It's more work. Getting it wrong can be dangerous if finalizers manage
> explicitly allocated memory.
It doesn't have to be more work for the programmer. In the simplest
case, the code that allocates objects simply checks the guardian,
finalizing/deallocating waiting objects, allocates a new object, and
registers the new object with the guardian, before returning the new
object. Most details can be encapsulated in the allocation code, even
if more complex mechanisms are used, e.g., when a separate
asynchronous thread is used to finalize objects collected on a
guardian. The only case where it might be more work is when the
programmer does want to do finalization in a particular. This case is
trivial in the topological finalization model because you always get
topological ordering, which either works or doesn't work.
Since there is equal danger in getting finalizer code wrong for either
system, I assume that you are indicating that there is additional risk
that the programmer will never query a guardian, while the collector
can ensure that finalizers are always run. While this is strictly
true, there are simple ways (described above) that guardians can be
used to ensure that guardians are always checked at reasonable
intervals. Here again, I think the greatest risks are in areas that
are disallowed using topological finalization. I generally favor
erring on the side of putting power in the hands of programmers rather
than tying their hands to save them from themselves.
> 2) It relies on global information, which the programmer shouldn't need to
> know. If my finalizer for type A objects invokes a method on a type B object
> references, I need to take special precautions if and only if type B objects
> also require finalization. I shouldn't have to know that. If B is a charact
> string represented as a cord (see my previous message), I would have to know
> whether a string I use happened to be built out of a sufficiently long file,
> and whether any of those characters survived editing, something I really don'
> want to know this. The garbage collector already determines the righ kind of
> global information.
Using guardians I would simply register type A objects with one guardian
and type B objects with another guardian, and always finalize all objects
on the type A guardian before finalizing objects on a type B guardian.
The information is not global; it can be limited to the implementation of
the A and B types.
You appear most concerned with C++ applications where the collector's
topological ordering is _one_ correct finalization order and you wish
to preserve and utilize this ordering information that the collector
derives. I (and perhaps a few others) believe that topological
ordering is too restrictive for general purpose finalization and that
other correct finalization orders are simple enough to derive and
implement without being an undue burden on the programmer.
Carl Bruggeman -- firstname.lastname@example.org -- Phone: (817) 272-3600 Fax: 272-3784
Computer Science and Engineering Department -- University of Texas at Arlington