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

Print this page

        

@@ -25,21 +25,17 @@
 
 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 Finalizer

@@ -96,11 +92,13 @@
             remove();
         }
         try {
             Object finalizee = this.get();
             if (finalizee != null && !(finalizee instanceof java.lang.Enum)) {
-                invokeFinalizeMethod(finalizee);
+                JavaLangAccess jla = sun.misc.SharedSecrets.getJavaLangAccess();
+                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;

@@ -181,10 +181,18 @@
             super(g, "Finalizer");
         }
         public void run() {
             if (running)
                 return;
+            while (!VM.isBooted()) {
+                // delay until VM completes initialization
+                try {
+                    VM.awaitBooted();
+                } catch (InterruptedException x) {
+                    continue;
+                }
+            }
             running = true;
             for (;;) {
                 try {
                     Finalizer f = (Finalizer)queue.remove();
                     f.runFinalizer();