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:
sjfink 2011-02-03 15:00:56 +00:00
parent c4082442f2
commit 29b114928e
1 changed files with 727 additions and 684 deletions

View File

@ -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);