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

Attila Szegedi szegedia at
Wed Oct 10 14:00:59 UTC 2018

> On 2018. Oct 10., at 11:39, Luke Hutchison <luke.hutch at> wrote:
> So given a class
> 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?
> 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 – statically decidable – existence of the call to reachabilityFence with “this” being passed into it (or call to anything else really… System.out.println would do too) is enough to ensure that the reference must live until at least the fence call was invoked (note: not necessarily until it returns, but that’s academical).

There’s no race condition. FWIW, most of these optimizations only kick in after inlining - someMethod() would get inlined into the body of the method that created the new A() instance and then the resulting merged code with inlined body can be analyzed as a unit. I think you would most likely not even notice this in scenarios that don’t involve inlining, but honestly it’s possible to have a JIT that could decide to mark a local variable dead immediately after it got loaded on stack for a call if there are no further uses of it.

Even so, from reachability point of view it’s an atomic operation to pop the arguments off the stack in the caller frame and assign them to parameter local variables in the callee frame. Having a gap in the reachability while transitioning from caller context to callee context would be a glaring bug indeed.


More information about the jdk-dev mailing list