[9] RFR (M): 8079205: CallSite dependency tracking is broken after sun.misc.Cleaner became automatically cleared (original) (raw)

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Fri May 8 17:16:38 UTC 2015


http://cr.openjdk.java.net/~vlivanov/8079205/webrev.01 https://bugs.openjdk.java.net/browse/JDK-8079205

Recent change in sun.misc.Cleaner behavior broke CallSite context cleanup.

CallSite references context class through a Cleaner to avoid its unnecessary retention.

The problem is the following: to do a cleanup (invalidate all affected nmethods) VM needs a pointer to a context class. Until Cleaner is cleared (and it was a manual action, since Cleaner extends PhantomReference isn't automatically cleared according to the docs), VM can extract it from CallSite.context.referent field.

I experimented with moving cleanup logic into VM [1], but Peter Levart came up with a clever idea and implemented FinalReference-based cleaner-like Finalizator. Classes don't have finalizers, but Finalizator allows to attach a finalization action to them. And it is guaranteed that the referent is alive when finalization happens.

Also, Peter spotted another problem with Cleaner-based implementation. Cleaner cleanup action is strongly referenced, since it is registered in Cleaner class. CallSite context cleanup action keeps a reference to CallSite class (it is passed to MHN.invalidateDependentNMethods). Users are free to extend CallSite and many do so. If a context class and a call site class are loaded by a custom class loader, such loader will never be unloaded, causing a memory leak.

Finalizator doesn't suffer from that, since the action is referenced only from Finalizator instance. The downside is that cleanup action can be missed if Finalizator becomes unreachable. It's not a problem for CallSite context, because a context is always referenced from some CallSite and if a CallSite becomes unreachable, there's no need to perform a cleanup.

Testing: jdk/test/java/lang/invoke, hotspot/test/compiler/jsr292

Contributed-by: plevart, vlivanov

Best regards, Vladimir Ivanov

PS: frankly speaking, I would move Finalizator from java.lang.ref to java.lang.invoke and call it Context, if there were a way to extend package-private FinalReference from another package :-)

[1] http://cr.openjdk.java.net/~vlivanov/8079205/webrev.00



More information about the core-libs-dev mailing list