src/share/classes/java/lang/ref/Finalizer.java

Print this page

        

@@ -25,24 +25,21 @@
 
 package java.lang.ref;
 
 import java.security.PrivilegedAction;
 import java.security.AccessController;
-
+import sun.misc.JavaLangAccess;
+import sun.misc.VM;
 
 final class Finalizer extends FinalReference<Object> { /* 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<Object> queue = new ReferenceQueue<>();
     private static Finalizer unfinalized = null;
     private static final Object lock = new Object();
+    private static JavaLangAccess jla = null;
 
     private Finalizer
         next = null,
         prev = null;
 

@@ -96,11 +93,12 @@
             remove();
         }
         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;
             }
         } catch (Throwable x) { }

@@ -139,10 +137,11 @@
                 }});
     }
 
     /* Called by Runtime.runFinalization() */
     static void runFinalization() {
+        assert VM.isBooted();
         forkSecondaryFinalizer(new Runnable() {
             private volatile boolean running;
             public void run() {
                 if (running)
                     return;

@@ -156,10 +155,11 @@
         });
     }
 
     /* Invoked by java.lang.Shutdown */
     static void runAllFinalizers() {
+        assert VM.isBooted();
         forkSecondaryFinalizer(new Runnable() {
             private volatile boolean running;
             public void run() {
                 if (running)
                     return;

@@ -173,18 +173,33 @@
                     }
                     f.runFinalizer();
                 }}});
     }
 
+    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) {
             super(g, "Finalizer");
         }
         public void run() {
             if (running)
                 return;
+
+            // ensure JavaLangAccess is available
+            ensureAccessAvailable();
             running = true;
             for (;;) {
                 try {
                     Finalizer f = (Finalizer)queue.remove();
                     f.runFinalizer();