use of com.squareup.haha.perflib.RootObj 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);
}
Aggregations