There's also a visibility issue here: The finalizer thread has to see the state
of the impls array after the last call to doSomething() for any of this to be useful.
Logically, the point at which an object is no longer kept reachable needs to have
release semantics.
To be honest, I don't find either the use of "native" here, or the association of
the property with a field, very natural. There's nothing terribly special about
the my_index field. The use of finalizers may be motivated by native code, but
often it won't be.
Within the current proposal, one could add a field
volatile boolean done;
and
1) have doSomething() (and perhaps the constructor) set "done" as the last thing
it does, instead of synchronizing on this.
2) have the finalizer read done (and basically ignore the value) as the
first thing it does.
In my view, that's both more efficient and less clean than what I wrote.
I think Bill and/or Jerry previously suggested adding a special call to indicate
object reachability. It effectively writes to a hidden volatile fireld in the
object which is always implicitly read by the finalizer. If we could call it
Object.reachable(), then doSomething() becomes:
public long doSomething() {
resource my_impl;
synchronized(impls) {
if (!taken[my_index]) throw new Error();
my_impl = impls[my_index];
}
long result = my_impl.doSomething();
reachable();
return result;
}
and the finalizer only needs to synchronize on impls. I'm perfectly happy with
that. But it's clearly not backward compatible with existing VMs, and hence would need
to be an addition to the current reachability rules, not a replacement. (I suspect that
adding a method to Object is not really feasible, so you would really have to say
something like System.reachable(this), but I'm not sure I understand all the issues
there.)
I'm satisfied that what we have now is usable. And anything you write using the proposed
rules is likely to work on existing VMs. And we're not breaking anything that wasn't
already broken. That's a great improvement over the current state of affairs, and I don't
think we need to go further than that, but we may want to.
Hans
-----Original Message-----
From: Sylvia Else
Sent: Thursday, November 20, 2003 7:00 PM
To: javamemorymodel@cs.umd.edu
Subject: Re: JavaMemoryModel: finalization review
At 04:22 PM 20/11/2003 -0800, Boehm, Hans wrote:
I spent a little bit of time revising an example of finalization
use in Java I had constructed earlier. I think is fairly representative
of a reasonable class of finalization uses.
Hans' example illustrates what a heavyweight approach to solving the underlying problem using synchronization is.
Essentially, the problem to be solved is that there is a form of reachability from the running thread to the external resource that the GC cannot see. The fix is to ensure that reachability of the external resource implies reachability of the wrapper class, which the GC can see.
Using synchronization in this way is not merely counter intuitive, but imposes a synchronization cost (and associated serialization) on every access to the external resource, even when this may not otherwise be required.
Implementors have objected to the idea of ensuring that a thread can reach its this object until it returns on the grounds that it prevents some optimisations, such as tail call elimination.
How about we extend the language to allow the (admittedly overloaded) native word to be used on a field. The semantics would be that the containing object will not be finalized while a method that references the field is in progress (from the programmer's perspective). This would limit the optimisations, but only for these methods.
According the VM spec, setting another bit in the field attributes can be done without breaking existing VMs (though a program that needs it is probably broken on such VMs anyway).
Sylvia.
-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:54 EDT