use of com.squareup.haha.perflib.ClassObj in project leakcanary by square.
the class HahaHelper method extendsThread.
static boolean extendsThread(ClassObj clazz) {
boolean extendsThread = false;
ClassObj parentClass = clazz;
while (parentClass.getSuperClassObj() != null) {
if (clazz.getClassName().equals(Thread.class.getName())) {
extendsThread = true;
break;
}
parentClass = parentClass.getSuperClassObj();
}
return extendsThread;
}
use of com.squareup.haha.perflib.ClassObj in project leakcanary by square.
the class HeapAnalyzer method buildLeakElement.
private LeakTraceElement buildLeakElement(LeakNode node) {
if (node.parent == null) {
// Ignore any root node.
return null;
}
Instance holder = node.parent.instance;
if (holder instanceof RootObj) {
return null;
}
LeakTraceElement.Type type = node.referenceType;
String referenceName = node.referenceName;
LeakTraceElement.Holder holderType;
String className;
String extra = null;
List<String> fields = describeFields(holder);
className = getClassName(holder);
if (holder instanceof ClassObj) {
holderType = CLASS;
} else if (holder instanceof ArrayInstance) {
holderType = ARRAY;
} else {
ClassObj classObj = holder.getClassObj();
if (extendsThread(classObj)) {
holderType = THREAD;
String threadName = threadName(holder);
extra = "(named '" + threadName + "')";
} else if (className.matches(ANONYMOUS_CLASS_NAME_PATTERN)) {
String parentClassName = classObj.getSuperClassObj().getClassName();
if (Object.class.getName().equals(parentClassName)) {
holderType = OBJECT;
try {
// This is an anonymous class implementing an interface. The API does not give access
// to the interfaces implemented by the class. We check if it's in the class path and
// use that instead.
Class<?> actualClass = Class.forName(classObj.getClassName());
Class<?>[] interfaces = actualClass.getInterfaces();
if (interfaces.length > 0) {
Class<?> implementedInterface = interfaces[0];
extra = "(anonymous implementation of " + implementedInterface.getName() + ")";
} else {
extra = "(anonymous subclass of java.lang.Object)";
}
} catch (ClassNotFoundException ignored) {
}
} else {
holderType = OBJECT;
// Makes it easier to figure out which anonymous class we're looking at.
extra = "(anonymous subclass of " + parentClassName + ")";
}
} else {
holderType = OBJECT;
}
}
return new LeakTraceElement(referenceName, type, holderType, className, extra, node.exclusion, fields);
}
use of com.squareup.haha.perflib.ClassObj in project leakcanary by square.
the class ShortestPathFinder method visitClassObj.
private void visitClassObj(LeakNode node) {
ClassObj classObj = (ClassObj) node.instance;
Map<String, Exclusion> ignoredStaticFields = excludedRefs.staticFieldNameByClassName.get(classObj.getClassName());
for (Map.Entry<Field, Object> entry : classObj.getStaticFieldValues().entrySet()) {
Field field = entry.getKey();
if (field.getType() != Type.OBJECT) {
continue;
}
String fieldName = field.getName();
if (fieldName.equals("$staticOverhead")) {
continue;
}
Instance child = (Instance) entry.getValue();
boolean visit = true;
if (ignoredStaticFields != null) {
Exclusion params = ignoredStaticFields.get(fieldName);
if (params != null) {
visit = false;
if (!params.alwaysExclude) {
enqueue(params, node, child, fieldName, STATIC_FIELD);
}
}
}
if (visit) {
enqueue(null, node, child, fieldName, STATIC_FIELD);
}
}
}
use of com.squareup.haha.perflib.ClassObj in project leakcanary by square.
the class HahaHelperTest method addStringClassToSnapshotWithFields.
private void addStringClassToSnapshotWithFields(Snapshot snapshot, Field[] fields) {
ClassObj charArrayClass = new ClassObj(0, null, "char[]", 0);
snapshot.addClass(CHAR_ARRAY_CLASS_ID, charArrayClass);
ClassObj stringClass = new ClassObj(0, null, "string", 0);
stringClass.setFields(fields);
snapshot.addClass(STRING_CLASS_ID, stringClass);
}
use of com.squareup.haha.perflib.ClassObj in project leakcanary by square.
the class HeapAnalyzer method describeFields.
private List<String> describeFields(Instance instance) {
List<String> fields = new ArrayList<>();
if (instance instanceof ClassObj) {
ClassObj classObj = (ClassObj) instance;
for (Map.Entry<Field, Object> entry : classObj.getStaticFieldValues().entrySet()) {
Field field = entry.getKey();
Object value = entry.getValue();
fields.add("static " + field.getName() + " = " + value);
}
} else if (instance instanceof ArrayInstance) {
ArrayInstance arrayInstance = (ArrayInstance) instance;
if (arrayInstance.getArrayType() == Type.OBJECT) {
Object[] values = arrayInstance.getValues();
for (int i = 0; i < values.length; i++) {
fields.add("[" + i + "] = " + values[i]);
}
}
} else {
ClassObj classObj = instance.getClassObj();
for (Map.Entry<Field, Object> entry : classObj.getStaticFieldValues().entrySet()) {
fields.add("static " + fieldToString(entry));
}
ClassInstance classInstance = (ClassInstance) instance;
for (ClassInstance.FieldValue field : classInstance.getValues()) {
fields.add(fieldToString(field));
}
}
return fields;
}
Aggregations