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();