--- old/src/share/classes/java/lang/ref/Finalizer.java 2013-11-01 14:00:16.000000000 -0700 +++ new/src/share/classes/java/lang/ref/Finalizer.java 2013-11-01 14:00:15.000000000 -0700 @@ -27,20 +27,17 @@ import java.security.PrivilegedAction; import java.security.AccessController; - +import sun.misc.JavaLangAccess; +import sun.misc.VM; final class Finalizer extends FinalReference { /* Package-private; must be in same package as the Reference class */ - /* A native method that invokes an arbitrary object's finalize method is - required since the finalize method is protected - */ - static native void invokeFinalizeMethod(Object o) throws Throwable; - private static ReferenceQueue queue = new ReferenceQueue<>(); private static Finalizer unfinalized = null; private static final Object lock = new Object(); + private static JavaLangAccess jla = null; private Finalizer next = null, @@ -98,7 +95,8 @@ try { Object finalizee = this.get(); if (finalizee != null && !(finalizee instanceof java.lang.Enum)) { - invokeFinalizeMethod(finalizee); + jla.invokeFinalize(finalizee); + /* Clear stack slot containing this variable, to decrease the chances of false retention with a conservative GC */ finalizee = null; @@ -141,6 +139,7 @@ /* Called by Runtime.runFinalization() */ static void runFinalization() { + assert VM.isBooted(); forkSecondaryFinalizer(new Runnable() { private volatile boolean running; public void run() { @@ -158,6 +157,7 @@ /* Invoked by java.lang.Shutdown */ static void runAllFinalizers() { + assert VM.isBooted(); forkSecondaryFinalizer(new Runnable() { private volatile boolean running; public void run() { @@ -175,6 +175,18 @@ }}}); } + private static void ensureAccessAvailable() { + while (!VM.isBooted()) { + // delay ntil VM completes initialization + try { + VM.awaitBooted(); + } catch (InterruptedException x) { + continue; + } + } + jla = sun.misc.SharedSecrets.getJavaLangAccess(); + } + private static class FinalizerThread extends Thread { private volatile boolean running; FinalizerThread(ThreadGroup g) { @@ -183,6 +195,9 @@ public void run() { if (running) return; + + // ensure JavaLangAccess is available + ensureAccessAvailable(); running = true; for (;;) { try {