/* * Copyright (c) 1997, 2017, 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 * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
/* * The Original Code is HAT. The Initial Developer of the * Original Code is Bill Foote, with contributions from others * at JavaSoft/Sun.
*/
privatestaticfinal JavaClass[] EMPTY_CLASS_ARRAY = new JavaClass[0]; // my subclasses private JavaClass[] subclasses = EMPTY_CLASS_ARRAY;
// my instances private Vector<JavaHeapObject> instances = new Vector<JavaHeapObject>();
// Who I belong to. Set on resolve. private Snapshot mySnapshot;
// Size of an instance, including VM overhead privateint instanceSize; // Total number of fields including inherited ones privateint totalNumFields;
public JavaClass(long id, String name, long superclassId, long loaderId, long signersId, long protDomainId,
JavaField[] fields, JavaStatic[] statics, int instanceSize) { this.id = id; this.name = name; this.superclass = new JavaObjectRef(superclassId); this.loader = new JavaObjectRef(loaderId); this.signers = new JavaObjectRef(signersId); this.protectionDomain = new JavaObjectRef(protDomainId); this.fields = fields; this.statics = statics; this.instanceSize = instanceSize;
}
public JavaClass(String name, long superclassId, long loaderId, long signersId, long protDomainId,
JavaField[] fields, JavaStatic[] statics, int instanceSize) { this(-1L, name, superclassId, loaderId, signersId,
protDomainId, fields, statics, instanceSize);
}
for (int i = 0; i < statics.length; i++) {
statics[i].resolve(this, snapshot);
}
snapshot.getJavaLangClass().addInstance(this); super.resolve(snapshot); return;
}
/** * Resolve our superclass. This might be called well before * all instances are available (like when reading deferred * instances in a 1.2 dump file :-) Calling this is sufficient * to be able to explore this class' fields.
*/ publicvoid resolveSuperclass(Snapshot snapshot) { if (superclass == null) { // We must be java.lang.Object, so we have no superclass.
} else {
totalNumFields = fields.length;
superclass = superclass.dereference(snapshot, null); if (superclass == snapshot.getNullThing()) {
superclass = null;
} else { try {
JavaClass sc = (JavaClass) superclass;
sc.resolveSuperclass(snapshot);
totalNumFields += sc.totalNumFields;
} catch (ClassCastException ex) {
System.out.println("Warning! Superclass of " + name + " is " + superclass);
superclass = null;
}
}
}
}
/** * Get a numbered field from this class
*/ public JavaField getField(int i) { if (i < 0 || i >= fields.length) { thrownew Error("No field " + i + " for " + name);
} return fields[i];
}
/** * Get the total number of fields that are part of an instance of * this class. That is, include superclasses.
*/ publicint getNumFieldsForInstance() { return totalNumFields;
}
/** * Get a numbered field from all the fields that are part of instance * of this class. That is, include superclasses.
*/ public JavaField getFieldForInstance(int i) { if (superclass != null) {
JavaClass sc = (JavaClass) superclass; if (i < sc.totalNumFields) { return sc.getFieldForInstance(i);
}
i -= sc.totalNumFields;
} return getField(i);
}
/** * Get the class responsible for field i, where i is a field number that * could be passed into getFieldForInstance. * * @see JavaClass.getFieldForInstance()
*/ public JavaClass getClassForField(int i) { if (superclass != null) {
JavaClass sc = (JavaClass) superclass; if (i < sc.totalNumFields) { return sc.getClassForField(i);
}
} returnthis;
}
public Enumeration<JavaHeapObject> getInstances(boolean includeSubclasses) { if (includeSubclasses) {
Enumeration<JavaHeapObject> res = instances.elements(); for (int i = 0; i < subclasses.length; i++) {
res = new CompositeEnumeration(res,
subclasses[i].getInstances(true));
} return res;
} else { return instances.elements();
}
}
/** * @return a count of the instances of this class
*/ publicint getInstancesCount(boolean includeSubclasses) { int result = instances.size(); if (includeSubclasses) { for (int i = 0; i < subclasses.length; i++) {
result += subclasses[i].getInstancesCount(includeSubclasses);
}
} return result;
}
public JavaClass[] getSubclasses() { return subclasses;
}
/** * This can only safely be called after resolve()
*/ public JavaClass getSuperclass() { return (JavaClass) superclass;
}
/** * This can only safely be called after resolve()
*/ public JavaThing getLoader() { return loader;
}
/** * This can only safely be called after resolve()
*/ publicboolean isBootstrap() { return loader == mySnapshot.getNullThing();
}
/** * This can only safely be called after resolve()
*/ public JavaThing getSigners() { return signers;
}
/** * This can only safely be called after resolve()
*/ public JavaThing getProtectionDomain() { return protectionDomain;
}
public JavaField[] getFields() { return fields;
}
/** * Includes superclass fields
*/ public JavaField[] getFieldsForInstance() {
Vector<JavaField> v = new Vector<JavaField>();
addFields(v);
JavaField[] result = new JavaField[v.size()]; for (int i = 0; i < v.size(); i++) {
result[i] = v.elementAt(i);
} return result;
}
public JavaStatic[] getStatics() { return statics;
}
// returns value of static field of given name public JavaThing getStaticField(String name) { for (int i = 0; i < statics.length; i++) {
JavaStatic s = statics[i]; if (s.getField().getName().equals(name)) { return s.getValue();
}
} returnnull;
}
public String toString() { return"class " + name;
}
/** * @return true iff a variable of type this is assignable from an instance * of other
*/ publicboolean isAssignableFrom(JavaClass other) { if (this == other) { returntrue;
} elseif (other == null) { returnfalse;
} else { return isAssignableFrom((JavaClass) other.superclass); // Trivial tail recursion: I have faith in javac.
}
}
/** * Describe the reference that this thing has to target. This will only * be called if target is in the array returned by getChildrenForRootset.
*/ public String describeReferenceTo(JavaThing target, Snapshot ss) { for (int i = 0; i < statics.length; i++) {
JavaField f = statics[i].getField(); if (f.hasId()) {
JavaThing other = statics[i].getValue(); if (other == target) { return"static field " + f.getName();
}
}
} returnsuper.describeReferenceTo(target, ss);
}
/** * @return the size of an instance of this class. Gives 0 for an array * type.
*/ publicint getInstanceSize() { return instanceSize + mySnapshot.getMinimumObjectSize();
}
/** * @return The size of all instances of this class. Correctly handles * arrays.
*/ publiclong getTotalInstanceSize() { int count = instances.size(); if (count == 0 || !isArray()) { return count * instanceSize;
}
// array class and non-zero count, we have to // get the size of each instance and sum it long result = 0; for (int i = 0; i < count; i++) {
JavaThing t = (JavaThing) instances.elementAt(i);
result += t.getSize();
} return result;
}
/** * @return the size of this object
*/
@Override publiclong getSize() {
JavaClass cl = mySnapshot.getJavaLangClass(); if (cl == null) { return 0;
} else { return cl.getInstanceSize();
}
}
JavaThing other;
other = getLoader(); if (other instanceof JavaHeapObject) {
v.visit((JavaHeapObject)other);
}
other = getSigners(); if (other instanceof JavaHeapObject) {
v.visit((JavaHeapObject)other);
}
other = getProtectionDomain(); if (other instanceof JavaHeapObject) {
v.visit((JavaHeapObject)other);
}
for (int i = 0; i < statics.length; i++) {
JavaField f = statics[i].getField(); if (!v.exclude(this, f) && f.hasId()) {
other = statics[i].getValue(); if (other instanceof JavaHeapObject) {
v.visit((JavaHeapObject) other);
}
}
}
}
// package-privates below this point final ReadBuffer getReadBuffer() { return mySnapshot.getReadBuffer();
}
// Internals only below this point privatevoid addFields(Vector<JavaField> v) { if (superclass != null) {
((JavaClass) superclass).addFields(v);
} for (int i = 0; i < fields.length; i++) {
v.addElement(fields[i]);
}
}
privatevoid addSubclassInstances(Vector<JavaHeapObject> v) { for (int i = 0; i < subclasses.length; i++) {
subclasses[i].addSubclassInstances(v);
} for (int i = 0; i < instances.size(); i++) {
v.addElement(instances.elementAt(i));
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.