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 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 }
50
51 private void add() {
52 synchronized (lock) {
53 if (unfinalized != null) {
54 this.next = unfinalized;
201 while (!VM.isBooted()) {
202 // delay until VM completes initialization
203 try {
204 VM.awaitBooted();
205 } catch (InterruptedException x) {
206 // ignore and continue
207 }
208 }
209 final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
210 running = true;
211 for (;;) {
212 try {
213 Finalizer f = (Finalizer)queue.remove();
214 f.runFinalizer(jla);
215 } catch (InterruptedException x) {
216 // ignore and continue
217 }
218 }
219 }
220 }
221
222 static {
223 ThreadGroup tg = Thread.currentThread().getThreadGroup();
224 for (ThreadGroup tgn = tg;
225 tgn != null;
226 tg = tgn, tgn = tg.getParent());
227 Thread finalizer = new FinalizerThread(tg);
228 finalizer.setPriority(Thread.MAX_PRIORITY - 2);
229 finalizer.setDaemon(true);
230 finalizer.start();
231 }
232
233 }
|
1 /*
2 * Copyright (c) 1997, 2015, 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 sun.misc.JavaLangAccess;
31 import sun.misc.ManagedLocalsThread;
32 import sun.misc.SharedSecrets;
33 import sun.misc.VM;
34
35 import java.util.Map;
36 import java.util.HashMap;
37 import java.util.Map.Entry;
38 import java.util.Arrays;
39
40 final class Finalizer extends FinalReference<Object> { /* Package-private; must be in
41 same package as the Reference
42 class */
43
44 private static ReferenceQueue<Object> queue = new ReferenceQueue<>();
45 private static Finalizer unfinalized = null;
46 private static final Object lock = new Object();
47
48 private Finalizer
49 next = null,
50 prev = null;
51
52 private boolean hasBeenFinalized() {
53 return (next == this);
54 }
55
56 private void add() {
57 synchronized (lock) {
58 if (unfinalized != null) {
59 this.next = unfinalized;
206 while (!VM.isBooted()) {
207 // delay until VM completes initialization
208 try {
209 VM.awaitBooted();
210 } catch (InterruptedException x) {
211 // ignore and continue
212 }
213 }
214 final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
215 running = true;
216 for (;;) {
217 try {
218 Finalizer f = (Finalizer)queue.remove();
219 f.runFinalizer(jla);
220 } catch (InterruptedException x) {
221 // ignore and continue
222 }
223 }
224 }
225 }
226
227 // Support for GC.finalizer_info DCMD
228
229 // Fileds of the class below is accessed directly by VM
230 // using hardcoded field offsets, so don't change
231 // class layout.
232 static class FinalizerHistogramEntry {
233 private final int count;
234 private final String name;
235
236 int getCount() { return count; }
237
238 FinalizerHistogramEntry(Map.Entry<String, int[]> e) {
239 name = e.getKey();
240 count = e.getValue()[0];
241 }
242 };
243
244 // This method called by VM from FinalizerInfoDCmd and
245 @SuppressWarnings({"unchecked","rawtypes"})
246 static Object[] getFinalizerHistogram() {
247 Map<String, int[]> countMap = new HashMap<>();
248 queue.forEach(r -> {
249 Object referent = r.get();
250 if (referent != null) {
251 countMap.computeIfAbsent(
252 referent.getClass().getName(), k -> new int[1])[0]++;
253 /* Clear stack slot containing this variable, to decrease
254 the chances of false retention with a conservative GC */
255 referent = null;
256 }
257 });
258
259 // Copy HashMap entry set to array of objects accessible from VM
260 FinalizerHistogramEntry fhe[] = new FinalizerHistogramEntry[countMap.size()];
261 int i = 0;
262 for (Map.Entry<String, int[]> e : countMap.entrySet()) {
263 fhe[i++] = new FinalizerHistogramEntry(e);
264 }
265
266 Arrays.sort(fhe, (e1, e2) -> Integer.compare(e2.getCount(), e1.getCount()));
267 return fhe;
268 }
269
270
271 static {
272 ThreadGroup tg = Thread.currentThread().getThreadGroup();
273 for (ThreadGroup tgn = tg;
274 tgn != null;
275 tg = tgn, tgn = tg.getParent());
276 Thread finalizer = new FinalizerThread(tg);
277 finalizer.setPriority(Thread.MAX_PRIORITY - 2);
278 finalizer.setDaemon(true);
279 finalizer.start();
280 }
281
282 }
|