use of com.squareup.haha.perflib.ArrayInstance in project leakcanary by square.
the class HeapAnalyzer method computeIgnoredBitmapRetainedSize.
/**
* Bitmaps and bitmap byte arrays are sometimes held by native gc roots, so they aren't included
* in the retained size because their root dominator is a native gc root.
* To fix this, we check if the leaking instance is a dominator for each bitmap instance and then
* add the bitmap size.
*
* From experience, we've found that bitmap created in code (Bitmap.createBitmap()) are correctly
* accounted for, however bitmaps set in layouts are not.
*/
private int computeIgnoredBitmapRetainedSize(Snapshot snapshot, Instance leakingInstance) {
int bitmapRetainedSize = 0;
ClassObj bitmapClass = snapshot.findClass("android.graphics.Bitmap");
for (Instance bitmapInstance : bitmapClass.getInstancesList()) {
if (isIgnoredDominator(leakingInstance, bitmapInstance)) {
ArrayInstance mBufferInstance = fieldValue(classInstanceValues(bitmapInstance), "mBuffer");
// Native bitmaps have mBuffer set to null. We sadly can't account for them.
if (mBufferInstance == null) {
continue;
}
long bufferSize = mBufferInstance.getTotalRetainedSize();
long bitmapSize = bitmapInstance.getTotalRetainedSize();
// the buffer is large, it's easy to detect by checking for bitmap size < buffer size.
if (bitmapSize < bufferSize) {
bitmapSize += bufferSize;
}
bitmapRetainedSize += bitmapSize;
}
}
return bitmapRetainedSize;
}
use of com.squareup.haha.perflib.ArrayInstance in project leakcanary by square.
the class HeapAnalyzer method getClassName.
private String getClassName(Instance instance) {
String className;
if (instance instanceof ClassObj) {
ClassObj classObj = (ClassObj) instance;
className = classObj.getClassName();
} else if (instance instanceof ArrayInstance) {
ArrayInstance arrayInstance = (ArrayInstance) instance;
className = arrayInstance.getClassObj().getClassName();
} else {
ClassObj classObj = instance.getClassObj();
className = classObj.getClassName();
}
return className;
}
use of com.squareup.haha.perflib.ArrayInstance in project leakcanary by square.
the class ShortestPathFinder method visitArrayInstance.
private void visitArrayInstance(LeakNode node) {
ArrayInstance arrayInstance = (ArrayInstance) node.instance;
Type arrayType = arrayInstance.getArrayType();
if (arrayType == Type.OBJECT) {
Object[] values = arrayInstance.getValues();
for (int i = 0; i < values.length; i++) {
Instance child = (Instance) values[i];
enqueue(null, node, child, "[" + i + "]", ARRAY_ENTRY);
}
}
}
use of com.squareup.haha.perflib.ArrayInstance 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.ArrayInstance in project leakcanary by square.
the class HahaHelperTest method createCharArrayValueInstance.
private void createCharArrayValueInstance() {
ArrayInstance valueArrayInstance = new ArrayInstance(0, null, Type.CHAR, VALUE_ARRAY_LENGTH, 0);
snapshot.addInstance(VALUE_ARRAY_INSTANCE_ID, valueArrayInstance);
}
Aggregations