[Gc] Re: Defeating finalization
Hans.Boehm at hp.com
Fri Apr 21 08:56:13 PDT 2006
On Fri, 21 Apr 2006, Ludovic [iso-8859-1] Courtès wrote:
> So you mean that it's safe to create new references to the object being
> finalized from within the finalizer? It is guaranteed that the GC will
> not reclaim an object's storage if its finalizer creates new references
> to it?
> My expectation was that the GC might behave as follow:
> if (object_is_unreachable (obj))
> invoke_finalizer (obj);
> GC_free (obj);
> In this case, creating new references to OBJ from within the finalizer
> would have been a bad idea.
It always waits for another cycle to collect the object. However, I
should have mentioned that you do need to set GC_java_finalization to make
sure that objects reachable from the finalizer are traced after
finalizability is determined. If you use the normal topologically-ordered
finalization mechanism, that's not necesary, since such objects are
already traced while determining finalizability.
> > Note that neither  nor our current GC implementation pays
> > sufficient attention to what I would now consider to be by far the
> > most serious issue with finalizers/guardians/weak-pointers/...:
> > Objects may be unreachable while one of their methods (or a function
> > taking the object as a parameter) is still running and accessing some
> > external state associated with the object. See for example the slides
> > at
> > http://www.hpl.hp.com/personal/Hans_Boehm/misc_slides/java_finalizers.pdf
> > .
> Maybe I don't understand the issue well enough, but it seems that the
> problem your slides are referring to mostly stems from the fact that in
> Java, "[e]ven if the client is single-threaded, finalizers run in their
> own thread," which brings a concurrency issue. Is this correct?
It's correct in the sense that if you have an absolutely single-threaded
executable, and don't remove objects from guardians while you might still
need the external object state, you should be safe. In my mind, the
problems with this are:
1) That's not a very convenient programming model. If a library
introduces a guardian, you need to occasionally make explicit calls back
into the library just in case something needs to be cleaned up, even if
you don't otherwise need it anymore. Finalization really wants threads.
2) Many interesting programs are already multithreaded, especially on
Windowsi, where it seems to be the vast majority. And we expect
that to become more so shortly.
We've been thinking about making a similar approach work with threads by
not finalizing objects until all threads have indicated that they have
passed a "finalization" safe point. But I don't currently know how to
make that work in a way that's not even uglier and less convenient than
the current Java solution. Ideas are welcome. (And good ones might make
it into the C++ standard.)
More information about the Gc