Re: JavaMemoryModel: Finalization idioms

From: Hans Boehm (Hans.Boehm@hp.com)
Date: Sun May 01 2005 - 14:37:10 EDT


On Sun, 1 May 2005, Jeremy Manson wrote:

> Hans Boehm wrote:
> > Thanks. More details follow.
> >
> > How do you implement keepAlive in Java code? You really want to
> > ensure visibility of writes (to outside the object) from ordinary
> > methods to finalizer code. I think that means that without the
> > implicit volatile read in the finalizer, you need an explicit
> > read or other synchronization action in the finalizer, too.
>
> You do need something at the finalizer. IIRC, the code looks like this:
>
> public class FinalizerHelp {
> static volatile Object v;
> public static void keepAlive(Object o) {
> v = o;
> v = null;
> }
> public static void doFinalize() {
> Object o = v;
> }
> }
>
> and it works because it stores a reference to the object into the heap.
> Although doFinalize is nasty, it is cleaner looking than lots of
> volatile stuff / empty sync blocks, at any rate.
Good point. That is a correct way to make the volatile variable static,
and thus keep it out of the class instances. And we had discussed it
earlier.

What I don't like it about is that it introduces a shared and frequently
written static field. How the performance compares to the empty
synchronized block is unclear to me. If the volatile write misses
the cache most of the time, because another processor wrote it last (not
unlikely), and I have to wait for completion of the write (perhaps
not unlikely because of the second volatile write), this is potentially
appreciably slower than the empty synchronized block.

(I would guess that the empty synchronized block costs 15-400 cycles
on a modern processor, depending on the platform. The cache miss is
probably closer to the high end of that on all modern machines,
especially large SMPs.)
>
> >
> > You usually end up with an otherwise unnecessary volatile field,
> > which either costs you space or potential contention (if you make
> > its static). And you end up with assignments everywhere you would
> > have the empty sync blocks.
>
> On the other hand, an assignment is probably cheaper than a lock
> acquisition, and it is nice to have the volatile field as documentation
> of "hey, we want to be able to finalize this object".
Maybe. But it seems to me that you are really going to introduce
the field where you introduce the finalizer, so it seems a bit
redundant.
>
>
> Definitely. Number 1: "Avoid finalizers" ;)

That will be suggested early in the talk.

But I think rule number 2 has to be

"Don't write your own GC to avoid finalizers."
>
> Jeremy
>
-------------------------------
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