Search in sources :

Example 1 with ArrayInstance

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;
}
Also used : ClassObj(com.squareup.haha.perflib.ClassObj) Instance(com.squareup.haha.perflib.Instance) ArrayInstance(com.squareup.haha.perflib.ArrayInstance) ClassInstance(com.squareup.haha.perflib.ClassInstance) ArrayInstance(com.squareup.haha.perflib.ArrayInstance)

Example 2 with ArrayInstance

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;
}
Also used : ClassObj(com.squareup.haha.perflib.ClassObj) HahaHelper.fieldToString(com.squareup.leakcanary.HahaHelper.fieldToString) HahaHelper.asString(com.squareup.leakcanary.HahaHelper.asString) ArrayInstance(com.squareup.haha.perflib.ArrayInstance)

Example 3 with ArrayInstance

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);
        }
    }
}
Also used : Type(com.squareup.haha.perflib.Type) RootType(com.squareup.haha.perflib.RootType) Instance(com.squareup.haha.perflib.Instance) ClassInstance(com.squareup.haha.perflib.ClassInstance) ArrayInstance(com.squareup.haha.perflib.ArrayInstance) ArrayInstance(com.squareup.haha.perflib.ArrayInstance)

Example 4 with ArrayInstance

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);
}
Also used : ClassObj(com.squareup.haha.perflib.ClassObj) Instance(com.squareup.haha.perflib.Instance) ArrayInstance(com.squareup.haha.perflib.ArrayInstance) ClassInstance(com.squareup.haha.perflib.ClassInstance) HahaHelper.fieldToString(com.squareup.leakcanary.HahaHelper.fieldToString) HahaHelper.asString(com.squareup.leakcanary.HahaHelper.asString) RootObj(com.squareup.haha.perflib.RootObj) ArrayInstance(com.squareup.haha.perflib.ArrayInstance)

Example 5 with ArrayInstance

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);
}
Also used : ArrayInstance(com.squareup.haha.perflib.ArrayInstance)

Aggregations

ArrayInstance (com.squareup.haha.perflib.ArrayInstance)8 ClassInstance (com.squareup.haha.perflib.ClassInstance)5 ClassObj (com.squareup.haha.perflib.ClassObj)4 Instance (com.squareup.haha.perflib.Instance)4 HahaHelper.asString (com.squareup.leakcanary.HahaHelper.asString)3 HahaHelper.fieldToString (com.squareup.leakcanary.HahaHelper.fieldToString)3 Field (com.squareup.haha.perflib.Field)1 Heap (com.squareup.haha.perflib.Heap)1 RootObj (com.squareup.haha.perflib.RootObj)1 RootType (com.squareup.haha.perflib.RootType)1 Type (com.squareup.haha.perflib.Type)1 THashMap (com.squareup.haha.trove.THashMap)1 HahaHelper.hasField (com.squareup.leakcanary.HahaHelper.hasField)1 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1