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

Andrew Haley aph at redhat.com
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
then.

> 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 redhat.com> 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. <https://www.redhat.com>
EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671


More information about the jdk-dev mailing list