src/java.base/share/classes/java/lang/ref/Finalizer.java
Print this page
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -30,10 +30,15 @@
import sun.misc.JavaLangAccess;
import sun.misc.ManagedLocalsThread;
import sun.misc.SharedSecrets;
import sun.misc.VM;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Map.Entry;
+import java.util.Arrays;
+
final class Finalizer extends FinalReference<Object> { /* Package-private; must be in
same package as the Reference
class */
private static ReferenceQueue<Object> queue = new ReferenceQueue<>();
@@ -217,10 +222,54 @@
}
}
}
}
+ // Support for GC.finalizer_info DCMD
+
+ // Fileds of the class below is accessed directly by VM
+ // using hardcoded field offsets, so don't change
+ // class layout.
+ static class FinalizerHistogramEntry {
+ private final int count;
+ private final String name;
+
+ int getCount() { return count; }
+
+ FinalizerHistogramEntry(Map.Entry<String, int[]> e) {
+ name = e.getKey();
+ count = e.getValue()[0];
+ }
+ };
+
+ // This method called by VM from FinalizerInfoDCmd and
+ @SuppressWarnings({"unchecked","rawtypes"})
+ static Object[] getFinalizerHistogram() {
+ Map<String, int[]> countMap = new HashMap<>();
+ queue.forEach(r -> {
+ Object referent = r.get();
+ if (referent != null) {
+ countMap.computeIfAbsent(
+ referent.getClass().getName(), k -> new int[1])[0]++;
+ /* Clear stack slot containing this variable, to decrease
+ the chances of false retention with a conservative GC */
+ referent = null;
+ }
+ });
+
+ // Copy HashMap entry set to array of objects accessible from VM
+ FinalizerHistogramEntry fhe[] = new FinalizerHistogramEntry[countMap.size()];
+ int i = 0;
+ for (Map.Entry<String, int[]> e : countMap.entrySet()) {
+ fhe[i++] = new FinalizerHistogramEntry(e);
+ }
+
+ Arrays.sort(fhe, (e1, e2) -> Integer.compare(e2.getCount(), e1.getCount()));
+ return fhe;
+ }
+
+
static {
ThreadGroup tg = Thread.currentThread().getThreadGroup();
for (ThreadGroup tgn = tg;
tgn != null;
tg = tgn, tgn = tg.getParent());