[jmm-dev] ECOOP, JVMLS
jeremymanson at google.com
Sun Aug 3 23:26:31 UTC 2014
On Sun, Aug 3, 2014 at 3:50 PM, David Holmes <david.holmes at oracle.com>
> On 4/08/2014 2:39 AM, Jeremy Manson wrote:
>> I brought finalization up with Aleksey at the summit. I have another
>> I assert that not providing stronger guarantees for finalization buys us
>> approximately nothing. A quick scan of a large code base suggests that
>> only 1/10K classes have finalizers. Optimizing something that rare is
>> deeply unlikely to buy us any performance in practice. On the flip side,
>> to provide a meaningful guarantee, all we need to do is add a bunch of
>> checks in the compiler that prevent making certain optimization choices
>> when an object is finalizable.
> But presumably the key here is to optimize the "is this object
> finalizable" check?
The JIT has to do it. And it's doing CHA anyway (and if there is a new
loaded class that invalidates the CHA, the method has to be
deoptimized/reoptimized anyway). So I'm not worried about the cost of
checking. Mostly, I'm worried that no one would want to do the surgery on
the JVM, since, IIRC, the original live range is thrown away before these
sorts of optimizations take place.
Furthermore, this is one of the rare cases in the model for which the weird
>> behavior comes up all the time in practice: I get questions from people
>> run into this behavior several times a year.
>> Furthermore, keepAlive() is going to confuse people. When people actually
>> remember to use it, it will make code less readable, and will likely
>> be sprinkled throughout the code in the same way that people add volatile:
>> as a mystic incantation that removes weird behavior. It's going to need
>> be average users - the consumers of a library - who need to use it, and
>> they will invariably need to run into this problem and debug it before
>> know they have to use it.
>> Instead of all of this, let's just make the strong guarantee that if an
>> object is transitively reachable from a local variable that is currently
>> scope (according to the bytecode's LVT), then the end of that scope
>> before the execution of the finalizer. Maybe we need to make certain
>> guarantees about other GC roots, too (although I'm not sure exactly which
>> it seems as if the class unloading semantics take care of most of them).
>> Then we forget about this topic forever.
> I think getting rid of the possibility that an object can be gc'd and
> finalized whilst a thread is in the middle of executing a method on that
> object would be good thing.
> I'm not sure what you just expressed about the scope is appropriate
> though. If you explicitly null a local and invoke GC you should expect to
> be able to trigger finalization of that instance.
Although providing a reachability guarantee for when the local variable
doesn't contain a reference to the object at the end of the scope would be
better, I don't know how to enforce it efficiently. The only way I can
imagine doing it is if you know the complete type of everything that might
be transitively reachable from an object whenever you assign to a local
variable that currently references that object. That starts to get beyond
what we might be able to do efficiently. I think! JIT experts, chime in
if I'm wrong.
(Of course, I guess with my guarantee, where you only get the guarantee if
the variable still contains a reference to the object when it goes out of
scope, it would still be confusing, so there's that downside. At least we
would still get the case where an object can be gc'd in the middle of
executing a method on it - the "this" reference would keep it alive.)
I wonder if we could say that, if you reassign / null a variable that
*directly* points to an object that is finalizable, then *that* provides
the happens before relationship we want. That would probably get most of
the rest of the cases we care about. It turns into something closer to
keepAlive in that case, but it wouldn't be quite so mystifying.
More information about the jmm-dev