< prev index next >
src/java.base/share/classes/java/lang/ref/Finalizer.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 64,74 ****
/* Invoked by VM */
static void register(Object finalizee) {
new Finalizer(finalizee);
}
! private void deregisterAndRunFinalizer(JavaLangAccess jla) {
synchronized (lock) {
if (this.next == this) // already finalized
return;
// unlink from unfinalized
if (unfinalized == this)
--- 64,74 ----
/* Invoked by VM */
static void register(Object finalizee) {
new Finalizer(finalizee);
}
! private void runFinalizer(JavaLangAccess jla) {
synchronized (lock) {
if (this.next == this) // already finalized
return;
// unlink from unfinalized
if (unfinalized == this)
*** 78,116 ****
if (this.next != null)
this.next.prev = this.prev;
this.prev = null;
this.next = this; // mark as finalized
}
- runFinalizer(jla);
- }
- private void runFinalizer(JavaLangAccess jla) {
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) { }
super.clear();
}
/* Create a privileged secondary finalizer thread in the system thread
! group for the given Runnable, and wait for it to complete.
!
! This method is used by both runFinalization and runFinalizersOnExit.
! The former method invokes all pending finalizers, while the latter
! invokes all uninvoked finalizers if on-exit finalization has been
! enabled.
!
! These two methods could have been implemented by offloading their work
! to the regular finalizer thread and waiting for that thread to finish.
! The advantage of creating a fresh thread, however, is that it insulates
! invokers of these methods from a stalled or deadlocked finalizer thread.
*/
private static void forkSecondaryFinalizer(final Runnable proc) {
AccessController.doPrivileged(
new PrivilegedAction<>() {
public Void run() {
--- 78,110 ----
if (this.next != null)
this.next.prev = this.prev;
this.prev = null;
this.next = this; // mark as finalized
}
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) { }
super.clear();
}
/* Create a privileged secondary finalizer thread in the system thread
! * group for the given Runnable, and wait for it to complete.
! *
! * This method is used by runFinalization.
! *
! * It could have been implemented by offloading their work to the
! * regular finalizer thread and waiting for that thread to finish.
! * The advantage of creating a fresh thread, however, is that it insulates
! * invokers of these methods from a stalled or deadlocked finalizer thread.
*/
private static void forkSecondaryFinalizer(final Runnable proc) {
AccessController.doPrivileged(
new PrivilegedAction<>() {
public Void run() {
*** 142,185 ****
if (running)
return;
final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
running = true;
for (Finalizer f; (f = (Finalizer)queue.poll()) != null; )
! f.deregisterAndRunFinalizer(jla);
}
});
}
- /* Invoked by java.lang.Shutdown */
- static void runAllFinalizers() {
- if (VM.initLevel() == 0) {
- return;
- }
-
- forkSecondaryFinalizer(new Runnable() {
- private volatile boolean running;
- public void run() {
- // in case of recursive call to run()
- if (running)
- return;
- final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
- running = true;
- for (;;) {
- // "pollFirst" from unfinalized
- Finalizer f;
- synchronized (lock) {
- f = unfinalized;
- if (f == null) break;
- unfinalized = f.next;
- if (unfinalized != null)
- unfinalized.prev = null;
- f.next = f; // mark as finalized
- }
- f.runFinalizer(jla);
- }}});
- }
-
private static class FinalizerThread extends Thread {
private volatile boolean running;
FinalizerThread(ThreadGroup g) {
super(g, null, "Finalizer", 0, false);
}
--- 136,150 ----
if (running)
return;
final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
running = true;
for (Finalizer f; (f = (Finalizer)queue.poll()) != null; )
! f.runFinalizer(jla);
}
});
}
private static class FinalizerThread extends Thread {
private volatile boolean running;
FinalizerThread(ThreadGroup g) {
super(g, null, "Finalizer", 0, false);
}
*** 201,211 ****
final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
running = true;
for (;;) {
try {
Finalizer f = (Finalizer)queue.remove();
! f.deregisterAndRunFinalizer(jla);
} catch (InterruptedException x) {
// ignore and continue
}
}
}
--- 166,176 ----
final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
running = true;
for (;;) {
try {
Finalizer f = (Finalizer)queue.remove();
! f.runFinalizer(jla);
} catch (InterruptedException x) {
// ignore and continue
}
}
}
< prev index next >