Finalizer being run while class still in use (escape analysis bug)

Andrew Haley aph at
Wed Oct 10 09:50:51 UTC 2018

On 10/10/2018 10:39 AM, Luke Hutchison wrote:
> class A {
>     void someMethod() {
>         try {
>             // ...
>         } finally {
>             Reference.reachabilityFence(this);
>         }
>     }
> }
> how is it that a call
> new A().someMethod()
> does not have a race condition between the "new A()" instance being
> invoked and reachability analysis realizing that there is a "this"
> reference in the finally block? Is it always true that there is an
> overlap between the reference to the invocation target being held
> and the reference to "this" in the method body being considered as
> reachable?

You need two threads to have a race condition. I'm not sure what
you're trying to ask: the reachabilityFence must run strictly after
the body of the try clause, and it the object will be reachable until

> Or stated as the inverse, is it guaranteed that there will be no gap in
> time (albeit infinitessimally small) between method invocation and the
> running of the method in which there will be no reference to the "new A()"
> object, where the finalizer could still be run?

The finalizer cannot be run as long as the object is reachable. The
object is reachable until the reachabilityFence.

> On Wed, Oct 10, 2018 at 3:16 AM Andrew Haley <aph at> wrote:
>>> I believe that I did not misread the spec, and that this is covered
>>> by the wording, "A reachable object is any object that can be
>>> accessed in any potential continuing computation from any live
>>> thread", since if a non-static method of an object is currently
>>> running, that object not only "can be accessed" by a live thread, it
>>> *is* currently being accessed by a live thread.
>> No. Believe it or not, a live method does not constitute an access
>> to an object. An object can die and be finalized even before one
>> if its methods is entered.
> That is highly surprising.

Yes, it is . You are not the first to be surprised by this.

> This makes finalizers a lot less reliable and more difficult to use
> than they could be.
> Wouldn't it make sense to consider the invocation targets in the stack
> during liveness analysis, so that out of the cases you gave, "finalizers
> may be run too soon (as here,) too late, or never", at least the "too soon"
> case is fixed?

We considered doing that; the discussion is online somewhere. I was in
favour of doing what you suggest, but there is some performance impact
of preserving liveness for all methods. In the end it was decided that
we'd provide reachabilityFence.

Andrew Haley
Java Platform Lead Engineer
Red Hat UK Ltd. <>
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671

More information about the jdk-dev mailing list