1 /* 2 * Copyright (c) 1997, 2008, 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 27 /* 28 * The Original Code is HAT. The Initial Developer of the 29 * Original Code is Bill Foote, with contributions from others 30 * at JavaSoft/Sun. 31 */ 32 33 package com.sun.tools.hat.internal.model; 34 35 import java.util.Vector; 36 import java.util.Hashtable; 37 import java.util.Enumeration; 38 39 import com.sun.tools.hat.internal.util.ArraySorter; 40 import com.sun.tools.hat.internal.util.Comparer; 41 42 /** 43 * @author A. Sundararajan 44 */ 45 46 public class ReachableObjects { 47 public ReachableObjects(JavaHeapObject root, 48 final ReachableExcludes excludes) { 49 this.root = root; 50 51 final Hashtable<JavaHeapObject, JavaHeapObject> bag = new Hashtable<JavaHeapObject, JavaHeapObject>(); 52 final Hashtable<String, String> fieldsExcluded = new Hashtable<String, String>(); //Bag<String> 53 final Hashtable<String, String> fieldsUsed = new Hashtable<String, String>(); // Bag<String> 54 JavaHeapObjectVisitor visitor = new AbstractJavaHeapObjectVisitor() { 55 public void visit(JavaHeapObject t) { 56 // Size is zero for things like integer fields 57 if (t != null && t.getSize() > 0 && bag.get(t) == null) { 58 bag.put(t, t); 59 t.visitReferencedObjects(this); 60 } 61 } 62 63 public boolean mightExclude() { 64 return excludes != null; 65 } 66 67 public boolean exclude(JavaClass clazz, JavaField f) { 68 if (excludes == null) { 69 return false; 70 } 71 String nm = clazz.getName() + "." + f.getName(); 72 if (excludes.isExcluded(nm)) { 73 fieldsExcluded.put(nm, nm); 74 return true; 75 } else { 76 fieldsUsed.put(nm, nm); 77 return false; 78 } 79 } 80 }; 81 // Put the closure of root and all objects reachable from root into 82 // bag (depth first), but don't include root: 83 visitor.visit(root); 84 bag.remove(root); 85 86 // Now grab the elements into a vector, and sort it in decreasing size 87 JavaThing[] things = new JavaThing[bag.size()]; 88 int i = 0; 89 for (Enumeration e = bag.elements(); e.hasMoreElements(); ) { 90 things[i++] = (JavaThing) e.nextElement(); 91 } 92 ArraySorter.sort(things, new Comparer() { 93 public int compare(Object lhs, Object rhs) { 94 JavaThing left = (JavaThing) lhs; 95 JavaThing right = (JavaThing) rhs; 96 int diff = right.getSize() - left.getSize(); 97 if (diff != 0) { 98 return diff; 99 } 100 return left.compareTo(right); 101 } 102 }); 103 this.reachables = things; 104 105 this.totalSize = root.getSize(); 106 for (i = 0; i < things.length; i++) { 107 this.totalSize += things[i].getSize(); 108 } 109 110 excludedFields = getElements(fieldsExcluded); 111 usedFields = getElements(fieldsUsed); 112 } 113 114 public JavaHeapObject getRoot() { 115 return root; 116 } 117 118 public JavaThing[] getReachables() { 119 return reachables; 120 } 121 122 public long getTotalSize() { 123 return totalSize; 124 } 125 126 public String[] getExcludedFields() { 127 return excludedFields; 128 } 129 130 public String[] getUsedFields() { 131 return usedFields; 132 } 133 134 private String[] getElements(Hashtable ht) { 135 Object[] keys = ht.keySet().toArray(); 136 int len = keys.length; 137 String[] res = new String[len]; 138 System.arraycopy(keys, 0, res, 0, len); 139 ArraySorter.sortArrayOfStrings(res); 140 return res; 141 } 142 143 private JavaHeapObject root; 144 private JavaThing[] reachables; 145 private String[] excludedFields; 146 private String[] usedFields; 147 private long totalSize; 148 }