1 /*
2 * Copyright (c) 1997, 2022, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24
25 /*
26 * The Original Code is HAT. The Initial Developer of the
27 * Original Code is Bill Foote, with contributions from others
28 * at JavaSoft/Sun.
29 */
30
31 package jdk.test.lib.hprof.model;
32
33 import java.util.Hashtable;
34 import java.util.Enumeration;
35
36 import jdk.test.lib.hprof.util.ArraySorter;
37 import jdk.test.lib.hprof.util.Comparer;
38
39 /**
40 * @author A. Sundararajan
41 */
42
43 public class ReachableObjects {
44 @SuppressWarnings("initialization")
45 public ReachableObjects(JavaHeapObject root,
46 final ReachableExcludes excludes) {
47 this.root = root;
48
49 final Hashtable<JavaHeapObject, JavaHeapObject> bag = new Hashtable<JavaHeapObject, JavaHeapObject>();
50 final Hashtable<String, String> fieldsExcluded = new Hashtable<String, String>(); //Bag<String>
51 final Hashtable<String, String> fieldsUsed = new Hashtable<String, String>(); // Bag<String>
52 JavaHeapObjectVisitor visitor = new AbstractJavaHeapObjectVisitor() {
53 public void visit(JavaHeapObject t) {
54 // Size is zero for things like integer fields
55 if (t != null && t.getSize() > 0 && bag.get(t) == null) {
56 bag.put(t, t);
57 t.visitReferencedObjects(this);
58 }
59 }
60
61 public boolean mightExclude() {
62 return excludes != null;
63 }
64
65 public boolean exclude(JavaClass clazz, JavaField f) {
66 if (excludes == null) {
67 return false;
68 }
69 String nm = clazz.getName() + "." + f.getName();
70 if (excludes.isExcluded(nm)) {
71 fieldsExcluded.put(nm, nm);
72 return true;
73 } else {
74 fieldsUsed.put(nm, nm);
75 return false;
76 }
77 }
78 };
79 // Put the closure of root and all objects reachable from root into
80 // bag (depth first), but don't include root:
81 visitor.visit(root);
82 bag.remove(root);
83
84 // Now grab the elements into a vector, and sort it in decreasing size
85 JavaThing[] things = new JavaThing[bag.size()];
86 int i = 0;
87 for (Enumeration<JavaHeapObject> e = bag.elements(); e.hasMoreElements(); ) {
88 things[i++] = (JavaThing) e.nextElement();
89 }
90 ArraySorter.sort(things, new Comparer() {
91 public int compare(Object lhs, Object rhs) {
92 JavaThing left = (JavaThing) lhs;
93 JavaThing right = (JavaThing) rhs;
94 long diff = right.getSize() - left.getSize();
95 if (diff != 0) {
96 return Long.signum(diff);
97 }
98 return left.compareTo(right);
99 }
100 });
101 this.reachables = things;
102
103 this.totalSize = root.getSize();
104 for (i = 0; i < things.length; i++) {
105 this.totalSize += things[i].getSize();
106 }
107
108 excludedFields = getElements(fieldsExcluded);
109 usedFields = getElements(fieldsUsed);
110 }
111
112 public JavaHeapObject getRoot() {
113 return root;
114 }
115
116 public JavaThing[] getReachables() {
117 return reachables;
118 }
119
120 public long getTotalSize() {
121 return totalSize;
122 }
123
124 public String[] getExcludedFields() {
125 return excludedFields;
126 }
127
128 public String[] getUsedFields() {
129 return usedFields;
130 }
131
132 private String[] getElements(Hashtable<?, ?> ht) {
133 Object[] keys = ht.keySet().toArray();
134 int len = keys.length;
135 String[] res = new String[len];
136 System.arraycopy(keys, 0, res, 0, len);
137 ArraySorter.sortArrayOfStrings(res);
138 return res;
139 }
140
141 private JavaHeapObject root;
142 private JavaThing[] reachables;
143 private String[] excludedFields;
144 private String[] usedFields;
145 private long totalSize;
146 }