minor cleanups. no semantic change
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@4047 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
c4082442f2
commit
29b114928e
|
@ -79,7 +79,8 @@ public class HeapTracer {
|
|||
* Classes that we should understand because they're internal to a container
|
||||
* object
|
||||
*/
|
||||
private static final HashSet<Class<?>> internalClasses = HashSetFactory.make();
|
||||
private static final HashSet<Class<?>> internalClasses = HashSetFactory
|
||||
.make();
|
||||
static {
|
||||
try {
|
||||
internalClasses.add(Class.forName("java.lang.String"));
|
||||
|
@ -87,17 +88,31 @@ public class HeapTracer {
|
|||
internalClasses.add(Class.forName("java.util.HashMap"));
|
||||
internalClasses.add(Class.forName("java.util.HashSet"));
|
||||
internalClasses.add(Class.forName("java.util.Vector"));
|
||||
internalClasses.add(Class.forName("com.ibm.wala.util.collections.SmallMap"));
|
||||
internalClasses.add(Class.forName("com.ibm.wala.util.collections.SimpleVector"));
|
||||
internalClasses.add(Class.forName("com.ibm.wala.util.intset.SimpleIntVector"));
|
||||
internalClasses.add(Class.forName("com.ibm.wala.util.intset.BasicNaturalRelation"));
|
||||
internalClasses.add(Class.forName("com.ibm.wala.util.intset.SparseIntSet"));
|
||||
internalClasses.add(Class.forName("com.ibm.wala.util.collections.SparseVector"));
|
||||
internalClasses.add(Class.forName("com.ibm.wala.util.intset.MutableSharedBitVectorIntSet"));
|
||||
internalClasses.add(Class.forName("com.ibm.wala.util.intset.MutableSparseIntSet"));
|
||||
internalClasses.add(Class.forName("com.ibm.wala.util.collections.TwoLevelVector"));
|
||||
internalClasses.add(Class.forName("com.ibm.wala.util.graph.impl.DelegatingNumberedNodeManager"));
|
||||
internalClasses.add(Class.forName("com.ibm.wala.util.graph.impl.SparseNumberedEdgeManager"));
|
||||
internalClasses.add(Class
|
||||
.forName("com.ibm.wala.util.collections.SmallMap"));
|
||||
internalClasses.add(Class
|
||||
.forName("com.ibm.wala.util.collections.SimpleVector"));
|
||||
internalClasses.add(Class
|
||||
.forName("com.ibm.wala.util.intset.SimpleIntVector"));
|
||||
internalClasses.add(Class
|
||||
.forName("com.ibm.wala.util.intset.BasicNaturalRelation"));
|
||||
internalClasses.add(Class
|
||||
.forName("com.ibm.wala.util.intset.SparseIntSet"));
|
||||
internalClasses.add(Class
|
||||
.forName("com.ibm.wala.util.collections.SparseVector"));
|
||||
internalClasses
|
||||
.add(Class
|
||||
.forName("com.ibm.wala.util.intset.MutableSharedBitVectorIntSet"));
|
||||
internalClasses.add(Class
|
||||
.forName("com.ibm.wala.util.intset.MutableSparseIntSet"));
|
||||
internalClasses.add(Class
|
||||
.forName("com.ibm.wala.util.collections.TwoLevelVector"));
|
||||
internalClasses
|
||||
.add(Class
|
||||
.forName("com.ibm.wala.util.graph.impl.DelegatingNumberedNodeManager"));
|
||||
internalClasses
|
||||
.add(Class
|
||||
.forName("com.ibm.wala.util.graph.impl.SparseNumberedEdgeManager"));
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
Assertions.UNREACHABLE();
|
||||
|
@ -206,12 +221,13 @@ public class HeapTracer {
|
|||
/**
|
||||
* Trace the heap and return the results
|
||||
*/
|
||||
public Result perform() throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException {
|
||||
public Result perform() throws ClassNotFoundException,
|
||||
IllegalArgumentException, IllegalAccessException {
|
||||
Result result = new Result();
|
||||
IdentityHashMap<Object, Object> objectsVisited = new IdentityHashMap<Object, Object>();
|
||||
if (traceStatics) {
|
||||
for (int i = 0; i < rootClasses.length; i++) {
|
||||
Class c = Class.forName(rootClasses[i]);
|
||||
Class<?> c = Class.forName(rootClasses[i]);
|
||||
Field[] fields = c.getDeclaredFields();
|
||||
for (int j = 0; j < fields.length; j++) {
|
||||
if (isStatic(fields[j])) {
|
||||
|
@ -220,9 +236,9 @@ public class HeapTracer {
|
|||
}
|
||||
}
|
||||
}
|
||||
for (Iterator it = rootInstances.iterator(); it.hasNext();) {
|
||||
for (Iterator<?> it = rootInstances.iterator(); it.hasNext();) {
|
||||
Object instance = it.next();
|
||||
Class c = instance.getClass();
|
||||
Class<?> c = instance.getClass();
|
||||
Set<Field> fields = getAllInstanceFields(c);
|
||||
for (Iterator<Field> it2 = fields.iterator(); it2.hasNext();) {
|
||||
Field f = it2.next();
|
||||
|
@ -239,9 +255,9 @@ public class HeapTracer {
|
|||
*/
|
||||
private static int computeSizeOf(Object o) {
|
||||
int result = BYTES_IN_HEADER;
|
||||
Class c = o.getClass();
|
||||
Class<?> c = o.getClass();
|
||||
if (c.isArray()) {
|
||||
Class elementType = c.getComponentType();
|
||||
Class<?> elementType = c.getComponentType();
|
||||
int length = Array.getLength(o);
|
||||
result += length * sizeOfSlot(elementType);
|
||||
} else if (c.isPrimitive()) {
|
||||
|
@ -261,7 +277,7 @@ public class HeapTracer {
|
|||
* @return the estimated size of the object
|
||||
*/
|
||||
private int sizeOf(Object o) {
|
||||
Class c = o.getClass();
|
||||
Class<?> c = o.getClass();
|
||||
if (c.isArray()) {
|
||||
return computeSizeOf(o);
|
||||
} else {
|
||||
|
@ -278,11 +294,12 @@ public class HeapTracer {
|
|||
* @param c
|
||||
* @return size of a field of type c, in bytes
|
||||
*/
|
||||
private static int sizeOfSlot(Class c) {
|
||||
private static int sizeOfSlot(Class<?> c) {
|
||||
if (!c.isPrimitive()) {
|
||||
return 4;
|
||||
} else {
|
||||
if (c.equals(Boolean.TYPE) || c.equals(Character.TYPE) || c.equals(Byte.TYPE)) {
|
||||
if (c.equals(Boolean.TYPE) || c.equals(Character.TYPE)
|
||||
|| c.equals(Byte.TYPE)) {
|
||||
return 1;
|
||||
} else if (c.equals(Short.TYPE)) {
|
||||
return 2;
|
||||
|
@ -303,8 +320,9 @@ public class HeapTracer {
|
|||
* @throws IllegalAccessException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
private void traverse(Field root, Result result, IdentityHashMap<Object, Object> objectsVisited) throws IllegalArgumentException,
|
||||
IllegalAccessException {
|
||||
private void traverse(Field root, Result result,
|
||||
IdentityHashMap<Object, Object> objectsVisited)
|
||||
throws IllegalArgumentException, IllegalAccessException {
|
||||
if (DEBUG) {
|
||||
System.err.println(("traverse root " + root));
|
||||
}
|
||||
|
@ -312,7 +330,7 @@ public class HeapTracer {
|
|||
Object contents = root.get(null);
|
||||
if (contents != null && (objectsVisited.get(contents) == null)) {
|
||||
objectsVisited.put(contents, DUMMY);
|
||||
Class c = contents.getClass();
|
||||
Class<?> c = contents.getClass();
|
||||
if (c.isArray()) {
|
||||
result.registerReachedFrom(root, root, contents);
|
||||
arrayWorkList.push(Pair.make(root, contents));
|
||||
|
@ -328,15 +346,19 @@ public class HeapTracer {
|
|||
drainWorkLists(root, result, objectsVisited);
|
||||
}
|
||||
|
||||
private void traverse(Field root, Object instance, Result result, IdentityHashMap<Object, Object> objectsVisited)
|
||||
private void traverse(Field root, Object instance, Result result,
|
||||
IdentityHashMap<Object, Object> objectsVisited)
|
||||
throws IllegalArgumentException, IllegalAccessException {
|
||||
|
||||
traverseFieldOfScalar(root, root, instance, null, objectsVisited, result);
|
||||
traverseFieldOfScalar(root, root, instance, null, objectsVisited,
|
||||
result);
|
||||
drainWorkLists(root, result, objectsVisited);
|
||||
}
|
||||
|
||||
|
||||
private void drainWorkLists(Field root, Result result, IdentityHashMap<Object, Object> objectsVisited) throws IllegalAccessException {
|
||||
@SuppressWarnings("rawtypes")
|
||||
private void drainWorkLists(Field root, Result result,
|
||||
IdentityHashMap<Object, Object> objectsVisited)
|
||||
throws IllegalAccessException {
|
||||
while (!scalarWorkList.isEmpty() || !arrayWorkList.isEmpty()) {
|
||||
if (!scalarWorkList.isEmpty()) {
|
||||
Object scalar = scalarWorkList.pop();
|
||||
|
@ -354,12 +376,13 @@ public class HeapTracer {
|
|||
}
|
||||
}
|
||||
|
||||
private void traverseArray(Field root, Object array, Object container, Result result, IdentityHashMap<Object, Object> objectsVisited)
|
||||
private void traverseArray(Field root, Object array, Object container,
|
||||
Result result, IdentityHashMap<Object, Object> objectsVisited)
|
||||
throws IllegalArgumentException {
|
||||
if (DEBUG) {
|
||||
System.err.println(("traverse array " + array.getClass()));
|
||||
}
|
||||
Class elementKlass = array.getClass().getComponentType();
|
||||
Class<?> elementKlass = array.getClass().getComponentType();
|
||||
if (elementKlass.isPrimitive()) {
|
||||
return;
|
||||
}
|
||||
|
@ -370,7 +393,7 @@ public class HeapTracer {
|
|||
|
||||
if (contents != null && (objectsVisited.get(contents) == null)) {
|
||||
objectsVisited.put(contents, DUMMY);
|
||||
Class klass = contents.getClass();
|
||||
Class<?> klass = contents.getClass();
|
||||
if (klass.isArray()) {
|
||||
result.registerReachedFrom(root, container, contents);
|
||||
contents = Pair.make(container, contents);
|
||||
|
@ -384,16 +407,18 @@ public class HeapTracer {
|
|||
}
|
||||
}
|
||||
|
||||
private void traverseScalar(Field root, Object scalar, Object container, Result result, IdentityHashMap<Object, Object> objectsVisited)
|
||||
private void traverseScalar(Field root, Object scalar, Object container,
|
||||
Result result, IdentityHashMap<Object, Object> objectsVisited)
|
||||
throws IllegalArgumentException, IllegalAccessException {
|
||||
|
||||
Class c = scalar.getClass();
|
||||
Class<?> c = scalar.getClass();
|
||||
if (DEBUG) {
|
||||
System.err.println(("traverse scalar " + c));
|
||||
}
|
||||
Field[] fields = getAllReferenceInstanceFields(c);
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
traverseFieldOfScalar(root, fields[i], scalar, container, objectsVisited, result);
|
||||
traverseFieldOfScalar(root, fields[i], scalar, container,
|
||||
objectsVisited, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -401,9 +426,10 @@ public class HeapTracer {
|
|||
|
||||
private final Object BAD = new Object();
|
||||
|
||||
private final HashMap<Package, Object> packageStatus = HashMapFactory.make();
|
||||
private final HashMap<Package, Object> packageStatus = HashMapFactory
|
||||
.make();
|
||||
|
||||
private final boolean isInBadPackage(Class c) {
|
||||
private final boolean isInBadPackage(Class<?> c) {
|
||||
Package p = c.getPackage();
|
||||
if (p == null) {
|
||||
return false;
|
||||
|
@ -440,8 +466,10 @@ public class HeapTracer {
|
|||
* @throws IllegalArgumentException
|
||||
* @throws IllegalAccessException
|
||||
*/
|
||||
private void traverseFieldOfScalar(Field root, Field f, Object scalar, Object container, IdentityHashMap<Object, Object> objectsVisited,
|
||||
Result result) throws IllegalArgumentException, IllegalAccessException {
|
||||
private void traverseFieldOfScalar(Field root, Field f, Object scalar,
|
||||
Object container, IdentityHashMap<Object, Object> objectsVisited,
|
||||
Result result) throws IllegalArgumentException,
|
||||
IllegalAccessException {
|
||||
// The following atrocious hack is needed to prevent the IBM 141 VM
|
||||
// from crashing
|
||||
if (isInBadPackage(f.getType())) {
|
||||
|
@ -459,7 +487,7 @@ public class HeapTracer {
|
|||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
Class klass = contents.getClass();
|
||||
Class<?> klass = contents.getClass();
|
||||
if (klass.isArray()) {
|
||||
result.registerReachedFrom(root, container, contents);
|
||||
contents = Pair.make(container, contents);
|
||||
|
@ -474,9 +502,9 @@ public class HeapTracer {
|
|||
}
|
||||
}
|
||||
|
||||
private static HashSet<Field> getAllInstanceFields(Class c) {
|
||||
private static HashSet<Field> getAllInstanceFields(Class<?> c) {
|
||||
HashSet<Field> result = HashSetFactory.make();
|
||||
Class klass = c;
|
||||
Class<?> klass = c;
|
||||
while (klass != null) {
|
||||
Field[] fields = klass.getDeclaredFields();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
|
@ -489,22 +517,23 @@ public class HeapTracer {
|
|||
return result;
|
||||
}
|
||||
|
||||
final private HashMap<Class, Field[]> allReferenceFieldsCache = HashMapFactory.make();
|
||||
final private HashMap<Class<?>, Field[]> allReferenceFieldsCache = HashMapFactory
|
||||
.make();
|
||||
|
||||
/**
|
||||
* @return Field[] representing reference instance fields of a class
|
||||
*/
|
||||
private Field[] getAllReferenceInstanceFields(Class c) {
|
||||
private Field[] getAllReferenceInstanceFields(Class<?> c) {
|
||||
if (allReferenceFieldsCache.containsKey(c))
|
||||
return allReferenceFieldsCache.get(c);
|
||||
else {
|
||||
HashSet<Field> s = HashSetFactory.make();
|
||||
Class klass = c;
|
||||
Class<?> klass = c;
|
||||
while (klass != null) {
|
||||
Field[] fields = klass.getDeclaredFields();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
if (!isStatic(fields[i])) {
|
||||
Class fc = fields[i].getType();
|
||||
Class<?> fc = fields[i].getType();
|
||||
if (!fc.isPrimitive()) {
|
||||
s.add(fields[i]);
|
||||
}
|
||||
|
@ -567,7 +596,8 @@ public class HeapTracer {
|
|||
* @param traceStatics
|
||||
* should all static fields be considered roots?
|
||||
*/
|
||||
public static HeapTracer.Result traceHeap(Collection instances, boolean traceStatics) {
|
||||
public static HeapTracer.Result traceHeap(Collection<?> instances,
|
||||
boolean traceStatics) {
|
||||
try {
|
||||
System.gc();
|
||||
System.gc();
|
||||
|
@ -578,7 +608,8 @@ public class HeapTracer {
|
|||
long f = Runtime.getRuntime().freeMemory();
|
||||
System.err.println(("Total Memory: " + t));
|
||||
System.err.println(("Occupied Memory: " + (t - f)));
|
||||
HeapTracer.Result r = (new HeapTracer(instances, traceStatics)).perform();
|
||||
HeapTracer.Result r = (new HeapTracer(instances, traceStatics))
|
||||
.perform();
|
||||
System.err.println("HeapTracer Analysis:");
|
||||
System.err.println(r.toString());
|
||||
return r;
|
||||
|
@ -601,12 +632,14 @@ public class HeapTracer {
|
|||
/**
|
||||
* mapping: Object (key) -> Integer (number of instances in a partition)
|
||||
*/
|
||||
private final HashMap<Object, Integer> instanceCount = HashMapFactory.make();
|
||||
private final HashMap<Object, Integer> instanceCount = HashMapFactory
|
||||
.make();
|
||||
|
||||
/**
|
||||
* mapping: Object (key) -> Integer (bytes)
|
||||
*/
|
||||
private final HashMap<Object, Integer> sizeCount = HashMapFactory.make();
|
||||
private final HashMap<Object, Integer> sizeCount = HashMapFactory
|
||||
.make();
|
||||
|
||||
/**
|
||||
* Total number of instances discovered
|
||||
|
@ -647,7 +680,8 @@ public class HeapTracer {
|
|||
Object key = it.next();
|
||||
Integer I = instanceCount.get(key);
|
||||
Integer bytes = sizeCount.get(key);
|
||||
result.append(" ").append(I).append(" ").append(bytes).append(" ");
|
||||
result.append(" ").append(I).append(" ").append(bytes)
|
||||
.append(" ");
|
||||
result.append(bytes.intValue() / I.intValue()).append(" ");
|
||||
result.append(key);
|
||||
result.append("\n");
|
||||
|
@ -656,12 +690,13 @@ public class HeapTracer {
|
|||
}
|
||||
|
||||
/**
|
||||
* compares two keys based on the total size of the heap traced from that
|
||||
* key
|
||||
* compares two keys based on the total size of the heap traced from
|
||||
* that key
|
||||
*/
|
||||
private class SizeComparator implements Comparator<Object> {
|
||||
/*
|
||||
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
|
||||
* @see java.util.Comparator#compare(java.lang.Object,
|
||||
* java.lang.Object)
|
||||
*/
|
||||
public int compare(Object o1, Object o2) {
|
||||
Integer i1 = sizeCount.get(o1);
|
||||
|
@ -695,11 +730,13 @@ public class HeapTracer {
|
|||
/**
|
||||
* a mapping from Field (static field roots) -> Demographics object
|
||||
*/
|
||||
private final HashMap<Field, Demographics> roots = HashMapFactory.make();
|
||||
private final HashMap<Field, Demographics> roots = HashMapFactory
|
||||
.make();
|
||||
|
||||
/**
|
||||
* @param root
|
||||
* @return the Demographics object tracking objects traced from that root
|
||||
* @return the Demographics object tracking objects traced from that
|
||||
* root
|
||||
*/
|
||||
private Demographics findOrCreateDemographics(Field root) {
|
||||
Demographics d = roots.get(root);
|
||||
|
@ -710,14 +747,17 @@ public class HeapTracer {
|
|||
return d;
|
||||
}
|
||||
|
||||
public void registerReachedFrom(Field root, Object predecessor, Object contents) {
|
||||
public void registerReachedFrom(Field root, Object predecessor,
|
||||
Object contents) {
|
||||
Demographics d = findOrCreateDemographics(root);
|
||||
d.registerObject(Pair.make(predecessor, contents.getClass()), contents);
|
||||
d.registerObject(Pair.make(predecessor, contents.getClass()),
|
||||
contents);
|
||||
}
|
||||
|
||||
public int getTotalSize() {
|
||||
int totalSize = 0;
|
||||
for (Iterator<Demographics> it = roots.values().iterator(); it.hasNext();) {
|
||||
for (Iterator<Demographics> it = roots.values().iterator(); it
|
||||
.hasNext();) {
|
||||
Demographics d = it.next();
|
||||
totalSize += d.getTotalSize();
|
||||
}
|
||||
|
@ -727,10 +767,12 @@ public class HeapTracer {
|
|||
@Override
|
||||
public String toString() {
|
||||
StringBuffer result = new StringBuffer();
|
||||
result.append("Assuming " + BYTES_IN_HEADER + " header bytes per object\n");
|
||||
result.append("Assuming " + BYTES_IN_HEADER
|
||||
+ " header bytes per object\n");
|
||||
int totalInstances = 0;
|
||||
int totalSize = 0;
|
||||
for (Iterator<Demographics> it = roots.values().iterator(); it.hasNext();) {
|
||||
for (Iterator<Demographics> it = roots.values().iterator(); it
|
||||
.hasNext();) {
|
||||
Demographics d = it.next();
|
||||
totalInstances += d.getTotalInstances();
|
||||
totalSize += d.getTotalSize();
|
||||
|
@ -753,12 +795,13 @@ public class HeapTracer {
|
|||
}
|
||||
|
||||
/**
|
||||
* compares two keys based on the total size of the heap traced from that
|
||||
* key
|
||||
* compares two keys based on the total size of the heap traced from
|
||||
* that key
|
||||
*/
|
||||
private class SizeComparator implements Comparator<Field> {
|
||||
/*
|
||||
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
|
||||
* @see java.util.Comparator#compare(java.lang.Object,
|
||||
* java.lang.Object)
|
||||
*/
|
||||
public int compare(Field o1, Field o2) {
|
||||
Demographics d1 = roots.get(o1);
|
||||
|
|
Loading…
Reference in New Issue