RE: JavaMemoryModel: Finalization idioms

From: Boehm, Hans (hans.boehm@hp.com)
Date: Tue May 03 2005 - 13:59:47 EDT


> -----Original Message-----
> From: Thomas Hawtin
> Sent: Monday, May 02, 2005 2:33 PM
>
> Boehm, Hans wrote:
> >
> > 1) Make all methods which might be the last ordinary call
> on an object
> > synchronized. Make the finalizer synchronized.
> >
> > 2) Write to a volatile field at the end of ordinary
> methods, and read
> > it first thing in the finalizer.
> >
> > 3) Put "synchronized(this){}" at the end of ordinary methods and at
> > the beginning of finalizers.
>
> Presumably to be absolutely correct 2 & 3 would need to be in finally
> blocks, although any problems would be incredibly obscure.
Yes. I currently don't mention that in my slides, though I should
probably mention it in passing.

I'm actually not sure how seriously to recommend that. For this
to break without the finally clause, you would need

1) The final call on an object terminates with an exception.
2) In spite of the exception, the final call updated state that
was needed by the finalizer, and
3) The compiler optimized for the exception case, and eliminated
a dead variable that was live on the non-exception path.
>
> I'm trying to work out anyway to make PhantomReferences behave
> reasonably. Any technique to keep the object object alive is
> going to be
> invisible to the ReferenceQueue handler.
>
That's an interesting point. I think Jeremy's technique of calling
keepAlive(this) in the object methods, where keepAlive stores the object
pointer in a static volatile, and then immediately clears it, works,
if you also read that volatile in the ReferenceQueue handler. I think
none of the other proposals do.

And the more I think about it, the less I like this approach, since it
inhibits processor-scalability of your code, for no legitimate reason.
With sufficiently many threads doing this, everyone will be contending
for the cache line holding the static volatile.

I think we really need keepAlive in the library. Perhaps java.lang.ref
is a good place to put it. If you implement in the standard
library, with suitable VM cooperation, it should be nearly free.
.NET has GC.KeepAlive which I believe can be used for this purpose,
though the primary motivation there seems to be different.

Hans

-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel



This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:01:10 EDT