src/share/classes/java/lang/ref/Finalizer.java
Print this page
*** 25,45 ****
package java.lang.ref;
import java.security.PrivilegedAction;
import java.security.AccessController;
!
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
--- 25,42 ----
package java.lang.ref;
import java.security.PrivilegedAction;
import java.security.AccessController;
! import sun.misc.JavaLangAccess;
! import sun.misc.SharedSecrets;
! import sun.misc.VM;
final class Finalizer extends FinalReference<Object> { /* Package-private; must be in
same package as the Reference
class */
private static ReferenceQueue<Object> queue = new ReferenceQueue<>();
private static Finalizer unfinalized = null;
private static final Object lock = new Object();
private Finalizer
*** 88,106 ****
/* Invoked by VM */
static void register(Object finalizee) {
new Finalizer(finalizee);
}
! private void runFinalizer() {
synchronized (this) {
if (hasBeenFinalized()) return;
remove();
}
try {
Object finalizee = this.get();
if (finalizee != null && !(finalizee instanceof java.lang.Enum)) {
! invokeFinalizeMethod(finalizee);
/* Clear stack slot containing this variable, to decrease
the chances of false retention with a conservative GC */
finalizee = null;
}
} catch (Throwable x) { }
--- 85,104 ----
/* Invoked by VM */
static void register(Object finalizee) {
new Finalizer(finalizee);
}
! private void runFinalizer(JavaLangAccess jla) {
synchronized (this) {
if (hasBeenFinalized()) return;
remove();
}
try {
Object finalizee = this.get();
if (finalizee != null && !(finalizee instanceof java.lang.Enum)) {
! 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,165 ****
}});
}
/* Called by Runtime.runFinalization() */
static void runFinalization() {
forkSecondaryFinalizer(new Runnable() {
private volatile boolean running;
public void run() {
if (running)
return;
running = true;
for (;;) {
Finalizer f = (Finalizer)queue.poll();
if (f == null) break;
! f.runFinalizer();
}
}
});
}
/* Invoked by java.lang.Shutdown */
static void runAllFinalizers() {
forkSecondaryFinalizer(new Runnable() {
private volatile boolean running;
public void run() {
if (running)
return;
--- 137,173 ----
}});
}
/* Called by Runtime.runFinalization() */
static void runFinalization() {
+ if (!VM.isBooted()) {
+ return;
+ }
+
+ final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
forkSecondaryFinalizer(new Runnable() {
private volatile boolean running;
public void run() {
if (running)
return;
running = true;
for (;;) {
Finalizer f = (Finalizer)queue.poll();
if (f == null) break;
! f.runFinalizer(jla);
}
}
});
}
/* Invoked by java.lang.Shutdown */
static void runAllFinalizers() {
+ if (!VM.isBooted()) {
+ return;
+ }
+
+ final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
forkSecondaryFinalizer(new Runnable() {
private volatile boolean running;
public void run() {
if (running)
return;
*** 169,179 ****
synchronized (lock) {
f = unfinalized;
if (f == null) break;
unfinalized = f.next;
}
! f.runFinalizer();
}}});
}
private static class FinalizerThread extends Thread {
private volatile boolean running;
--- 177,187 ----
synchronized (lock) {
f = unfinalized;
if (f == null) break;
unfinalized = f.next;
}
! f.runFinalizer(jla);
}}});
}
private static class FinalizerThread extends Thread {
private volatile boolean running;
*** 181,197 ****
super(g, "Finalizer");
}
public void run() {
if (running)
return;
running = true;
for (;;) {
try {
Finalizer f = (Finalizer)queue.remove();
! f.runFinalizer();
} catch (InterruptedException x) {
! continue;
}
}
}
}
--- 189,217 ----
super(g, "Finalizer");
}
public void run() {
if (running)
return;
+
+ // Finalizer thread starts before System.initializeSystemClass
+ // is called. Wait until JavaLangAccess is available
+ while (!VM.isBooted()) {
+ // delay until VM completes initialization
+ try {
+ VM.awaitBooted();
+ } catch (InterruptedException x) {
+ // ignore and continue
+ }
+ }
+ final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
running = true;
for (;;) {
try {
Finalizer f = (Finalizer)queue.remove();
! f.runFinalizer(jla);
} catch (InterruptedException x) {
! // ignore and continue
}
}
}
}