ReachableObjects.java revision 2224:2a8815d86b93
1/*
2 * Copyright (c) 1997, 2016, 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
33package jdk.test.lib.hprof.model;
34
35import java.util.Vector;
36import java.util.Hashtable;
37import java.util.Enumeration;
38
39import jdk.test.lib.hprof.util.ArraySorter;
40import jdk.test.lib.hprof.util.Comparer;
41
42/**
43 * @author      A. Sundararajan
44 */
45
46public 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<JavaHeapObject> 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}
149