< prev index next >

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

Print this page




  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.ref;
  27 
  28 import java.security.PrivilegedAction;
  29 import java.security.AccessController;




  30 import sun.misc.JavaLangAccess;
  31 import sun.misc.ManagedLocalsThread;
  32 import sun.misc.SharedSecrets;
  33 import sun.misc.VM;
  34 
  35 final class Finalizer extends FinalReference<Object> { /* Package-private; must be in
  36                                                           same package as the Reference
  37                                                           class */
  38 
  39     private static ReferenceQueue<Object> queue = new ReferenceQueue<>();
  40     private static Finalizer unfinalized = null;
  41     private static final Object lock = new Object();
  42 
  43     private Finalizer
  44         next = null,
  45         prev = null;
  46 
  47     private boolean hasBeenFinalized() {
  48         return (next == this);
  49     }


 167             return;
 168         }
 169 
 170         forkSecondaryFinalizer(new Runnable() {
 171             private volatile boolean running;
 172             public void run() {
 173                 // in case of recursive call to run()
 174                 if (running)
 175                     return;
 176                 final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
 177                 running = true;
 178                 for (;;) {
 179                     Finalizer f;
 180                     synchronized (lock) {
 181                         f = unfinalized;
 182                         if (f == null) break;
 183                         unfinalized = f.next;
 184                     }
 185                     f.runFinalizer(jla);
 186                 }}});


























 187     }
 188 
 189     private static class FinalizerThread extends ManagedLocalsThread {
 190         private volatile boolean running;
 191         FinalizerThread(ThreadGroup g) {
 192             super(g, "Finalizer");
 193         }
 194         public void run() {
 195             // in case of recursive call to run()
 196             if (running)
 197                 return;
 198 
 199             // Finalizer thread starts before System.initializeSystemClass
 200             // is called.  Wait until JavaLangAccess is available
 201             while (!VM.isBooted()) {
 202                 // delay until VM completes initialization
 203                 try {
 204                     VM.awaitBooted();
 205                 } catch (InterruptedException x) {
 206                     // ignore and continue




  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.ref;
  27 
  28 import java.security.PrivilegedAction;
  29 import java.security.AccessController;
  30 import java.util.Arrays;
  31 import java.util.HashMap;
  32 import java.util.Map;
  33 
  34 import sun.misc.JavaLangAccess;
  35 import sun.misc.ManagedLocalsThread;
  36 import sun.misc.SharedSecrets;
  37 import sun.misc.VM;
  38 
  39 final class Finalizer extends FinalReference<Object> { /* Package-private; must be in
  40                                                           same package as the Reference
  41                                                           class */
  42 
  43     private static ReferenceQueue<Object> queue = new ReferenceQueue<>();
  44     private static Finalizer unfinalized = null;
  45     private static final Object lock = new Object();
  46 
  47     private Finalizer
  48         next = null,
  49         prev = null;
  50 
  51     private boolean hasBeenFinalized() {
  52         return (next == this);
  53     }


 171             return;
 172         }
 173 
 174         forkSecondaryFinalizer(new Runnable() {
 175             private volatile boolean running;
 176             public void run() {
 177                 // in case of recursive call to run()
 178                 if (running)
 179                     return;
 180                 final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
 181                 running = true;
 182                 for (;;) {
 183                     Finalizer f;
 184                     synchronized (lock) {
 185                         f = unfinalized;
 186                         if (f == null) break;
 187                         unfinalized = f.next;
 188                     }
 189                     f.runFinalizer(jla);
 190                 }}});
 191     }
 192 
 193     static String printFinalizationQueue() {
 194         Map<String, int[]> countMap = new HashMap<>();
 195         queue.forEach(r -> {
 196             Object referent = r.get();
 197             if (referent != null) {
 198                 countMap.computeIfAbsent(
 199                     referent.getClass().getName(), k -> new int[1])[0]++;
 200                 /* Clear stack slot containing this variable, to decrease
 201                    the chances of false retention with a conservative GC */
 202                 referent = null;
 203             }
 204         });
 205         @SuppressWarnings("unchecked")
 206         Map.Entry<String, int[]>[] entries = countMap.entrySet().toArray(
 207             new Map.Entry[countMap.size()]
 208         );
 209         Arrays.sort(entries, (e1, e2) ->
 210             Integer.compare(e2.getValue()[0], e1.getValue()[0]));
 211         StringBuilder sb = new StringBuilder();
 212         for (Map.Entry<String, int[]> e : entries) {
 213             sb.append("Class: ").append(e.getKey())
 214               .append(" count: ").append(e.getValue()[0]).append("\n");
 215         }
 216         return sb.toString();
 217     }
 218 
 219     private static class FinalizerThread extends ManagedLocalsThread {
 220         private volatile boolean running;
 221         FinalizerThread(ThreadGroup g) {
 222             super(g, "Finalizer");
 223         }
 224         public void run() {
 225             // in case of recursive call to run()
 226             if (running)
 227                 return;
 228 
 229             // Finalizer thread starts before System.initializeSystemClass
 230             // is called.  Wait until JavaLangAccess is available
 231             while (!VM.isBooted()) {
 232                 // delay until VM completes initialization
 233                 try {
 234                     VM.awaitBooted();
 235                 } catch (InterruptedException x) {
 236                     // ignore and continue


< prev index next >