FileDocCategorySizeDatePackage
NativeAllocationInfo.javaAPI DocAndroid 1.5 API9788Wed May 06 22:41:08 BST 2009com.android.ddmlib

NativeAllocationInfo

public final class NativeAllocationInfo extends Object
Stores native allocation information.

Contains number of allocations, their size and the stack trace.

Note: the ddmlib does not resolve the stack trace automatically. While this class provides storage for resolved stack trace, this is merely for convenience.

Fields Summary
private static final int
FLAG_ZYGOTE_CHILD
private static final int
FLAG_MASK
private static ArrayList
sAllocFunctionFilter
list of alloc functions that are filtered out when attempting to display a relevant method responsible for an allocation
private final int
mSize
private final boolean
mIsZygoteChild
private final int
mAllocations
private final ArrayList
mStackCallAddresses
private ArrayList
mResolvedStackCall
private boolean
mIsStackCallResolved
Constructors Summary
NativeAllocationInfo(int size, int allocations)
Constructs a new {@link NativeAllocationInfo}.

param
size The size of the allocations.
param
allocations the allocation count


                          
        
        this.mSize = size & ~FLAG_MASK;
        this.mIsZygoteChild = ((size & FLAG_ZYGOTE_CHILD) != 0);
        this.mAllocations = allocations;
    
Methods Summary
voidaddStackCallAddress(long address)
Adds a stack call address for this allocation.

param
address The address to add.

        mStackCallAddresses.add(address);
    
public booleanequals(java.lang.Object obj)
Indicates whether some other object is "equal to" this one.

param
obj the reference object with which to compare.
return
true if this object is equal to the obj argument; false otherwise.
see
java.lang.Object#equals(java.lang.Object)

        if (obj == this)
            return true;
        if (obj instanceof NativeAllocationInfo) {
            NativeAllocationInfo mi = (NativeAllocationInfo)obj;
            // quick compare of size, alloc, and stackcall size
            if (mSize != mi.mSize || mAllocations != mi.mAllocations ||
                    mStackCallAddresses.size() != mi.mStackCallAddresses.size()) {
                return false;
            }
            // compare the stack addresses
            int count = mStackCallAddresses.size();
            for (int i = 0 ; i < count ; i++) {
                long a = mStackCallAddresses.get(i);
                long b = mi.mStackCallAddresses.get(i);
                if (a != b) {
                    return false;
                }
            }

            return true;
        }
        return false;
    
public intgetAllocationCount()
Returns the allocation count.

        return mAllocations;
    
public synchronized NativeStackCallInfogetRelevantStackCallInfo()
Returns the first {@link NativeStackCallInfo} that is relevant.

A relevant NativeStackCallInfo is a stack call that is not deep in the lower level of the libc, but the actual method that performed the allocation.

return
a NativeStackCallInfo or null if the stack call has not been processed from the raw addresses.
see
#setResolvedStackCall(ArrayList)
see
#isStackCallResolved()

        if (mIsStackCallResolved && mResolvedStackCall != null) {
            Iterator<NativeStackCallInfo> sourceIterator = mResolvedStackCall.iterator();
            Iterator<Long> addrIterator = mStackCallAddresses.iterator();

            while (sourceIterator.hasNext() && addrIterator.hasNext()) {
                long addr = addrIterator.next();
                NativeStackCallInfo info = sourceIterator.next();
                if (addr != 0 && info != null) {
                    if (isRelevant(info.getMethodName())) {
                        return info;
                    }
                }
            }

            // couldnt find a relevant one, so we'll return the first one if it
            // exists.
            if (mResolvedStackCall.size() > 0)
                return mResolvedStackCall.get(0);
        }

        return null;
    
public synchronized NativeStackCallInfo[]getResolvedStackCall()
Returns the resolved stack call.

return
An array of {@link NativeStackCallInfo} or null if the stack call was not resolved.
see
#setResolvedStackCall(ArrayList)
see
#isStackCallResolved()

        if (mIsStackCallResolved) {
            return mResolvedStackCall.toArray(new NativeStackCallInfo[mResolvedStackCall.size()]);
        }
        
        return null;
    
public intgetSize()
Returns the total size of this allocation.

        return mSize;
    
public java.lang.Long[]getStackCallAddresses()
Returns the stack call of this allocation as raw addresses.

return
the list of addresses where the allocation happened.

        return mStackCallAddresses.toArray(new Long[mStackCallAddresses.size()]);
    
private booleanisRelevant(java.lang.String methodName)
Returns true if the method name is relevant.

param
methodName the method name to test.

        for (String filter : sAllocFunctionFilter) {
            if (methodName.contains(filter)) {
                return false;
            }
        }
        
        return true;
    
public booleanisStackCallResolved()
Returns whether the stack call addresses have been resolved into {@link NativeStackCallInfo} objects.

        return mIsStackCallResolved;
    
public booleanisZygoteChild()
Returns whether the allocation happened in a child of the zygote process.

        return mIsZygoteChild;
    
public synchronized voidsetResolvedStackCall(java.util.List resolvedStackCall)
Sets the resolved stack call for this allocation.

If resolvedStackCall is non null then {@link #isStackCallResolved()} will return true after this call.

param
resolvedStackCall The list of {@link NativeStackCallInfo}.

        if (mResolvedStackCall == null) {
            mResolvedStackCall = new ArrayList<NativeStackCallInfo>();
        } else {
            mResolvedStackCall.clear();
        }
        mResolvedStackCall.addAll(resolvedStackCall);
        mIsStackCallResolved = mResolvedStackCall.size() != 0;
    
public java.lang.StringtoString()
Returns a string representation of the object.

see
java.lang.Object#toString()

        StringBuffer buffer = new StringBuffer();
        buffer.append("Allocations: ");
        buffer.append(mAllocations);
        buffer.append("\n"); //$NON-NLS-1$

        buffer.append("Size: ");
        buffer.append(mSize);
        buffer.append("\n"); //$NON-NLS-1$

        buffer.append("Total Size: ");
        buffer.append(mSize * mAllocations);
        buffer.append("\n"); //$NON-NLS-1$

        Iterator<Long> addrIterator = mStackCallAddresses.iterator();
        Iterator<NativeStackCallInfo> sourceIterator = mResolvedStackCall.iterator();

        while (sourceIterator.hasNext()) {
            long addr = addrIterator.next();
            NativeStackCallInfo source = sourceIterator.next();
            if (addr == 0)
                continue;

            if (source.getLineNumber() != -1) {
                buffer.append(String.format("\t%1$08x\t%2$s --- %3$s --- %4$s:%5$d\n", addr,
                        source.getLibraryName(), source.getMethodName(),
                        source.getSourceFile(), source.getLineNumber()));
            } else {
                buffer.append(String.format("\t%1$08x\t%2$s --- %3$s --- %4$s\n", addr,
                        source.getLibraryName(), source.getMethodName(), source.getSourceFile()));
            }
        }

        return buffer.toString();