[gclist] Buffy finalizer slayer.
Fri, 11 Jun 1999 23:27:52 -0700
On Jun 11, 1:58pm, Charles Fiterman wrote:
> Why would I turn the watcher into a finalizable object?
The point was that you could do essentially the same thing with topologically
ordered finalization, and vice-versa. Thus the difference between watcher
objects and finalizers is largely one of terminology and cosmetics. In either
case the collector communicates some facts about reachability back to the
mutator, and that's all it does.
> The point is to
> eliminate finalizers from the system as an active danger.
I'm arguing that they're no more or less dangerous than watcher objects.
> What happens at end of job?
In my view nothing special. You DON'T run finalizers. It's not safe to. If
you need to guarantee that something is run before job exit you need another
mechanism. Ditto for watcher objects, since some of these objects will still
> What environment do finalizers run in?
In their own thread, if there's more than one. Otherwise they are enqueued and
run explicitly by client code, just like in the watcher case.
> What if they throw an exception?
In the threaded case, I would ignore the exception.
> When the watchee becomes inaccessible the weak pointer in the watcher zeros
> and the mutator at a time of its choosing scans the watchers and discovers
> it. The mutator then becomes responsible for any sorting and knows the
> semantics of the problem. The mutator may simply put numbers in the watcher
> objects and qsort them which costs only C*n*log(n). All file objects get 2
> buffer objects get 1 everything else 0. Big deal, the user built these
> watcher objects and knows their relationships.
I disagree. There is no single "user". There are many programmers each one of
whom understands one or some collection of modules. If an A points to a B, and
a B points to a C, the implementation of A has no business knowing about C's
finalization requirements. Finalization order is a global issue that no
individual implementor should have to understand.
> Agreed it leaves genuine problem cases. Those must be solved by the user.
> They are a problem in the semantics of the mutator. Eliminating finalizers
> faces the user with his own bug.
Which is exactly the same as with topologically ordered finalization, once you
split each object into the part that's needed by the finalizer and the part
> >Similarly long finalization chains can still exist (though I have yet to
> see a
> >real case where those are a problem no matter what the finalization model).
> Agreed they can exist. But sorting them with qsort costs C*n*log(n) with a
> very small C. And the user determines the order. Those finalizers may be
> putting lines on a report. But worst case topological sort is either C*n*n
> in your version which has cycles and fails to report them or C*n*n*n in
> versions that correctly report cycles. In your version C is very large, you
> run a whole collection cycle. While in the reporting version C is small but
> n*n*n can explode.
This is an aside, but I believe our collector does correctly report the
existence of cycles, though it doesn't attempt to describe the complete cycle.
But I believe that could still be done in linear time per GC, though with a
more complex algorithm.
> I believe the only reason for the topological sort is not understanding the
> semantics of the mutator. If the user writes the sort there will generally
> be an invocation of qsort at worst. There may be cases where the user needs
> a topological sort and can't get around it. That should be the user's
> problem. Maybe the user needs simulated annealing to sort finalizers.
I disagree, but I'm not sure it makes sense to discuss this here again. I
don't think it's that important an issue. And your proposal does enforce
topological ordering. Assuming watchees point to watchers, if a watcher points
to a watchee because it needs it for finalization, one watchee will keep the
other live while it's needed for finalization.