[jmm-dev] ECOOP, JVMLS
ludwig.mark at siemens.com
Sun Aug 3 17:01:08 UTC 2014
Because of the historical problems with finalizers, we eliminated all
but the one that's /absolutely/ essential. We started learning about
the synchronization/deadlock problems with finalizers in the Netscape
Java 1.1 VM....
Examples of unnecessary finalizers were classes that encapsulated a
Socket. We concluded that the Socket class must take care of itself (so
have its own finalizer to tear down the connection, etc.), that our
finalizer to close the socket, etc. was just redundant.
P.S. It seems that there is an expectation of
punch-card-programming-like line wrapping in this list...?
From: jmm-dev [mailto:jmm-dev-bounces at openjdk.java.net] On Behalf Of Jeremy Manson
Sent: Sunday, August 03, 2014 11:39 AM
To: Aleksey Shipilev
Cc: jmm-dev at openjdk.java.net
Subject: Re: [jmm-dev] ECOOP, JVMLS
I brought finalization up with Aleksey at the summit. I have another idea.
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.
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 who
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 simply
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 to
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 they
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 in
scope (according to the bytecode's LVT), then the end of that scope happens
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.
On Sun, Aug 3, 2014 at 5:48 AM, Aleksey Shipilev <
aleksey.shipilev at oracle.com> wrote:
> On 08/03/2014 05:36 AM, Doug Lea wrote:
> > * Someone (other than Hans!) reminded me that something like the
> > reachabilityFence included in the never-shipped Fences API
> > (
> Yes, and I forgot to mention this use case highlighted to us at JVMLS.
> Basically, have a Java class which points to naked memory addresses
> (think DirectByteBuffer-like implementation). Your method takes that
> Java instance as the method argument, pulls the native memory address
> from its field and starts working with it. At some later point during
> the execution of that method, you hit safepoint, and VM figures the
> enclosing instance is not needed anymore (e.g. dataflow suggests no uses
> for that local in future) -- which arguably lets VM to run the cleanup
> mechanics, freeing up the referenced memory. VM resumes from GC,
> continues in the same method, boom, use-after-free.
More information about the jmm-dev