1 /* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 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.concurrent.ThreadLocalRandom; 31 import sun.misc.ManagedLocalsThread; 32 import sun.misc.SharedSecrets; 33 import sun.misc.VM; 34 35 /* Package-private; must be in same package as the Reference class */ 36 class Finalizer<T> extends FinalReference<T> implements Runnable { 37 /** 38 * Finalizers are registered in a doubly-linked list so that they are kept 39 * alive until discovered by VM, processed by ReferenceHandling pool and then 40 * unlinked. There are several lists to distribute Finalizers randomly into 41 * to reduce contention among concurrent threads trying to link/unlink them. 42 */ 43 static final FinalizerList[] unfinalized; 44 static { 45 int cpus = Runtime.getRuntime().availableProcessors(); 46 // smallest power of two equal or greater than 2 * # of CPUs 47 int lists = (cpus <= 1) ? 2 : Integer.highestOneBit(cpus - 1) << 2; 48 unfinalized = new FinalizerList[lists]; 49 for (int i = 0; i < lists; i++) { 50 unfinalized[i] = new FinalizerList(); 51 } 52 } 53 54 volatile Finalizer prev; 55 volatile Finalizer next; 56 private final int listIndex; 57 58 Finalizer(T finalizee, int listIndex) { 59 super(finalizee, ReferenceQueue.NULL); 60 this.listIndex = listIndex; 61 } 62 63 /** A constructor used for special Finalizer instances in FinalizerList */ 64 Finalizer() { 65 super(null, ReferenceQueue.NULL); 66 listIndex = -1; // never registered in any list 67 } 68 69 /** Invoked by VM for objects overriding finalize() method */ 70 static void register(Object finalizee) { 71 int rnd = nextSecondarySeed(); 72 int index = (rnd >>> 1) & (unfinalized.length - 1); 73 unfinalized[index].link(new Finalizer<>(finalizee, index), (rnd & 1) == 0); 74 } 75 76 @Override 77 public void run() { 78 T finalizee = delete(); 79 if (finalizee == null) { 80 return; 81 } 82 unfinalized[listIndex].unlink(this); 83 try { 84 if (!(finalizee instanceof java.lang.Enum)) { 85 invokeFinalizee(finalizee); 86 87 /* Clear stack slot containing this variable, to decrease 88 the chances of false retention with a conservative GC */ 89 finalizee = null; 90 } 91 } catch (Throwable x) { } 92 } 93 94 /* Invoke the finalize() method on the finalizee (overridden by Finalizator) */ 95 void invokeFinalizee(T finalizee) throws Throwable { 96 SharedSecrets.getJavaLangAccess().invokeFinalize(finalizee); 97 finalizee = null; 98 } 99 100 @Override 101 public void clear() { 102 T finalizee = delete(); 103 if (finalizee == null) { 104 return; 105 } 106 unfinalized[listIndex].unlink(this); 107 /* Clear stack slot containing this variable, to decrease 108 the chances of false retention with a conservative GC */ 109 finalizee = null; 110 } 111 112 /* Create a privileged secondary finalizer thread in the system thread 113 group for the given Runnable, and wait for it to complete. 114 115 This method is used by both runFinalization and runFinalizersOnExit. 116 The former method invokes all pending finalizers, while the latter 117 invokes all uninvoked finalizers if on-exit finalization has been 118 enabled. 119 120 These two methods could have been implemented by offloading their work 121 to the regular finalizer thread and waiting for that thread to finish. 122 The advantage of creating a fresh thread, however, is that it insulates 123 invokers of these methods from a stalled or deadlocked finalizer thread. 124 */ 125 private static void forkSecondaryFinalizer(final Runnable proc) { 126 AccessController.doPrivileged( 127 new PrivilegedAction<>() { 128 public Void run() { 129 ThreadGroup tg = Thread.currentThread().getThreadGroup(); 130 for (ThreadGroup tgn = tg; 131 tgn != null; 132 tg = tgn, tgn = tg.getParent()); 133 Thread sft = new ManagedLocalsThread(tg, proc, "Secondary finalizer"); 134 sft.start(); 135 try { 136 sft.join(); 137 } catch (InterruptedException x) { 138 Thread.currentThread().interrupt(); 139 } 140 return null; 141 }}); 142 } 143 144 /* Called by Runtime.runFinalization() */ 145 static void runFinalization() { 146 if (!VM.isBooted()) { 147 return; 148 } 149 150 forkSecondaryFinalizer(new Runnable() { 151 private volatile boolean running; 152 public void run() { 153 // in case of recursive call to run() 154 if (running) 155 return; 156 running = true; 157 ReferenceHandling.runFinalization(); 158 } 159 }); 160 } 161 162 /* Invoked by java.lang.Shutdown */ 163 static void runAllFinalizers() { 164 if (!VM.isBooted()) { 165 return; 166 } 167 168 forkSecondaryFinalizer(new Runnable() { 169 private volatile boolean running; 170 public void run() { 171 // in case of recursive call to run() 172 if (running) 173 return; 174 running = true; 175 for (FinalizerList uflist : unfinalized) 176 for (Finalizer<?> f = uflist.first(); f != null; f = uflist.succ(f)) { 177 f.run(); 178 }}}); 179 } 180 181 // Unsafe mechanics 182 183 /** 184 * Returns the pseudo-randomly initialized or updated secondary seed. 185 * Copied from ThreadLocalRandom due to package access restrictions. 186 */ 187 static int nextSecondarySeed() { 188 int r; 189 Thread t = Thread.currentThread(); 190 if ((r = UNSAFE.getInt(t, threadLocalRandomSecondarySeedOffset)) != 0) { 191 r ^= r << 13; // xorshift 192 r ^= r >>> 17; 193 r ^= r << 5; 194 } 195 else if ((r = ThreadLocalRandom.current().nextInt()) == 0) 196 r = 1; // avoid zero 197 UNSAFE.putInt(t, threadLocalRandomSecondarySeedOffset, r); 198 return r; 199 } 200 201 boolean isAlive() { 202 return getReferentVolatile() != null; 203 } 204 205 boolean isDeleted() { 206 return getReferentVolatile() == null; 207 } 208 209 private T delete() { 210 T referent = getReferentVolatile(); 211 return (referent != null) && casReferent(referent, null) 212 ? referent : null; 213 } 214 215 void lazySetNext(Finalizer<?> val) { 216 UNSAFE.putOrderedObject(this, nextOffset, val); 217 } 218 219 boolean casNext(Finalizer<?> cmp, Finalizer<?> val) { 220 return UNSAFE.compareAndSwapObject(this, nextOffset, cmp, val); 221 } 222 223 void lazySetPrev(Finalizer<?> val) { 224 UNSAFE.putOrderedObject(this, prevOffset, val); 225 } 226 227 boolean casPrev(Finalizer<?> cmp, Finalizer<?> val) { 228 return UNSAFE.compareAndSwapObject(this, prevOffset, cmp, val); 229 } 230 231 private static final sun.misc.Unsafe UNSAFE; 232 private static final long prevOffset; 233 private static final long nextOffset; 234 private static final long threadLocalRandomSecondarySeedOffset; 235 236 static { 237 try { 238 UNSAFE = sun.misc.Unsafe.getUnsafe(); 239 Class<Finalizer> fc = Finalizer.class; 240 prevOffset = UNSAFE.objectFieldOffset(fc.getDeclaredField("prev")); 241 nextOffset = UNSAFE.objectFieldOffset(fc.getDeclaredField("next")); 242 Class<Thread> tc = Thread.class; 243 threadLocalRandomSecondarySeedOffset = UNSAFE.objectFieldOffset 244 (tc.getDeclaredField("threadLocalRandomSecondarySeed")); 245 } catch (Exception e) { 246 throw new Error(e); 247 } 248 } 249 }