FileDocCategorySizeDatePackage
GcEventContainer.javaAPI DocAndroid 1.5 API14266Wed May 06 22:41:08 BST 2009com.android.ddmlib.log

GcEventContainer

public final class GcEventContainer extends EventContainer
Custom Event Container for the Gc event since this event doesn't simply output data in int or long format, but encodes several values on 4 longs.

The array of {@link EventValueDescription}s parsed from the "event-log-tags" file must be ignored, and instead, the array returned from {@link #getValueDescriptions()} must be used.

Fields Summary
public static final int
GC_EVENT_TAG
private String
processId
private long
gcTime
private long
bytesFreed
private long
objectsFreed
private long
actualSize
private long
allowedSize
private long
softLimit
private long
objectsAllocated
private long
bytesAllocated
private long
zActualSize
private long
zAllowedSize
private long
zObjectsAllocated
private long
zBytesAllocated
private long
dlmallocFootprint
private long
mallinfoTotalAllocatedSpace
private long
externalLimit
private long
externalBytesAllocated
Constructors Summary
GcEventContainer(com.android.ddmlib.log.LogReceiver.LogEntry entry, int tag, Object data)


          
        super(entry, tag, data);
        init(data);
    
GcEventContainer(int tag, int pid, int tid, int sec, int nsec, Object data)

        super(tag, pid, tid, sec, nsec, data);
        init(data);
    
Methods Summary
private static longfloat12ToInt(int f12)
Converts a 12 bit float representation into an unsigned int (returned as a long)

param
f12

        return (f12 & 0x1FF) << ((f12 >>> 9) * 4);
    
public EventValueTypegetType()

        return EventValueType.LIST;
    
public java.lang.ObjectgetValue(int valueIndex)

        if (valueIndex == 0) {
            return processId;
        }
        
        try {
            return new Long(getValueAsLong(valueIndex));
        } catch (InvalidTypeException e) {
            // this would only happened if valueIndex was 0, which we test above.
        }
        
        return null;
    
public doublegetValueAsDouble(int valueIndex)

        return (double)getValueAsLong(valueIndex);
    
private final longgetValueAsLong(int valueIndex)
Returns the long value of the valueIndex-th value.

param
valueIndex the index of the value.
throws
InvalidTypeException if index is 0 as it is a string value.

        switch (valueIndex) {
            case 0:
                throw new InvalidTypeException();
            case 1:
                return gcTime;
            case 2:
                return objectsFreed;
            case 3:
                return bytesFreed;
            case 4:
                return softLimit;
            case 5:
                return actualSize;
            case 6:
                return allowedSize;
            case 7:
                return objectsAllocated;
            case 8:
                return bytesAllocated;
            case 9:
                return actualSize - zActualSize;
            case 10:
                return allowedSize - zAllowedSize;
            case 11:
                return objectsAllocated - zObjectsAllocated;
            case 12:
                return bytesAllocated - zBytesAllocated;
            case 13:
               return zActualSize;
            case 14:
                return zAllowedSize;
            case 15:
                return zObjectsAllocated;
            case 16:
                return zBytesAllocated;
            case 17:
                return externalLimit;
            case 18:
                return externalBytesAllocated;
            case 19:
                return dlmallocFootprint;
            case 20:
                return mallinfoTotalAllocatedSpace;
        }

        throw new ArrayIndexOutOfBoundsException();
    
public java.lang.StringgetValueAsString(int valueIndex)

        switch (valueIndex) {
            case 0:
                return processId;
            default:
                try {
                    return Long.toString(getValueAsLong(valueIndex));
                } catch (InvalidTypeException e) {
                    // we shouldn't stop there since we test, in this method first.
                }
        }

        throw new ArrayIndexOutOfBoundsException();
    
static EventValueDescription[]getValueDescriptions()
Returns a custom array of {@link EventValueDescription} since the actual content of this event (list of (long, long) does not match the values encoded into those longs.

        try {
            return new EventValueDescription[] {
                    new EventValueDescription("Process Name", EventValueType.STRING),
                    new EventValueDescription("GC Time", EventValueType.LONG,
                            ValueType.MILLISECONDS),
                    new EventValueDescription("Freed Objects", EventValueType.LONG,
                            ValueType.OBJECTS),
                    new EventValueDescription("Freed Bytes", EventValueType.LONG, ValueType.BYTES),
                    new EventValueDescription("Soft Limit", EventValueType.LONG, ValueType.BYTES),
                    new EventValueDescription("Actual Size (aggregate)", EventValueType.LONG,
                            ValueType.BYTES),
                    new EventValueDescription("Allowed Size (aggregate)", EventValueType.LONG,
                            ValueType.BYTES),
                    new EventValueDescription("Allocated Objects (aggregate)",
                            EventValueType.LONG, ValueType.OBJECTS),
                    new EventValueDescription("Allocated Bytes (aggregate)", EventValueType.LONG,
                            ValueType.BYTES),
                    new EventValueDescription("Actual Size", EventValueType.LONG, ValueType.BYTES),
                    new EventValueDescription("Allowed Size", EventValueType.LONG, ValueType.BYTES),
                    new EventValueDescription("Allocated Objects", EventValueType.LONG,
                            ValueType.OBJECTS),
                    new EventValueDescription("Allocated Bytes", EventValueType.LONG,
                            ValueType.BYTES),
                    new EventValueDescription("Actual Size (zygote)", EventValueType.LONG,
                            ValueType.BYTES),
                    new EventValueDescription("Allowed Size (zygote)", EventValueType.LONG,
                            ValueType.BYTES),
                    new EventValueDescription("Allocated Objects (zygote)", EventValueType.LONG,
                            ValueType.OBJECTS),
                    new EventValueDescription("Allocated Bytes (zygote)", EventValueType.LONG,
                            ValueType.BYTES),
                    new EventValueDescription("External Allocation Limit", EventValueType.LONG,
                            ValueType.BYTES),
                    new EventValueDescription("External Bytes Allocated", EventValueType.LONG,
                            ValueType.BYTES),
                    new EventValueDescription("dlmalloc Footprint", EventValueType.LONG,
                            ValueType.BYTES),
                    new EventValueDescription("Malloc Info: Total Allocated Space",
                            EventValueType.LONG, ValueType.BYTES),
                  };
        } catch (InvalidValueTypeException e) {
            // this shouldn't happen since we control manual the EventValueType and the ValueType
            // values. For development purpose, we assert if this happens.
            assert false;
        }

        // this shouldn't happen, but the compiler complains otherwise.
        return null;
    
private voidinit(java.lang.Object data)

param
data

        if (data instanceof Object[]) {
            Object[] values = (Object[])data;
            for (int i = 0; i < values.length; i++) {
                if (values[i] instanceof Long) {
                    parseDvmHeapInfo((Long)values[i], i);
                }
            }
        }
    
private voidparseDvmHeapInfo(long data, int index)

        switch (index) {
            case 0:
                //    [63   ] Must be zero
                //    [62-24] ASCII process identifier
                //    [23-12] GC time in ms
                //    [11- 0] Bytes freed
                
                gcTime = float12ToInt((int)((data >> 12) & 0xFFFL));
                bytesFreed = float12ToInt((int)(data & 0xFFFL));
                
                // convert the long into an array, in the proper order so that we can convert the
                // first 5 char into a string.
                byte[] dataArray = new byte[8];
                put64bitsToArray(data, dataArray, 0);
                
                // get the name from the string
                processId = new String(dataArray, 0, 5);
                break;
            case 1:
                //    [63-62] 10
                //    [61-60] Reserved; must be zero
                //    [59-48] Objects freed
                //    [47-36] Actual size (current footprint)
                //    [35-24] Allowed size (current hard max)
                //    [23-12] Objects allocated
                //    [11- 0] Bytes allocated
                objectsFreed = float12ToInt((int)((data >> 48) & 0xFFFL));
                actualSize = float12ToInt((int)((data >> 36) & 0xFFFL));
                allowedSize = float12ToInt((int)((data >> 24) & 0xFFFL));
                objectsAllocated = float12ToInt((int)((data >> 12) & 0xFFFL));
                bytesAllocated = float12ToInt((int)(data & 0xFFFL));
                break;
            case 2:
                //    [63-62] 11
                //    [61-60] Reserved; must be zero
                //    [59-48] Soft limit (current soft max)
                //    [47-36] Actual size (current footprint)
                //    [35-24] Allowed size (current hard max)
                //    [23-12] Objects allocated
                //    [11- 0] Bytes allocated
                softLimit = float12ToInt((int)((data >> 48) & 0xFFFL));
                zActualSize = float12ToInt((int)((data >> 36) & 0xFFFL));
                zAllowedSize = float12ToInt((int)((data >> 24) & 0xFFFL));
                zObjectsAllocated = float12ToInt((int)((data >> 12) & 0xFFFL));
                zBytesAllocated = float12ToInt((int)(data & 0xFFFL));
                break;
            case 3:
                //    [63-48] Reserved; must be zero
                //    [47-36] dlmallocFootprint
                //    [35-24] mallinfo: total allocated space
                //    [23-12] External byte limit
                //    [11- 0] External bytes allocated
                dlmallocFootprint = float12ToInt((int)((data >> 36) & 0xFFFL));
                mallinfoTotalAllocatedSpace = float12ToInt((int)((data >> 24) & 0xFFFL));
                externalLimit = float12ToInt((int)((data >> 12) & 0xFFFL));
                externalBytesAllocated = float12ToInt((int)(data & 0xFFFL));
                break;
            default:
                break;
        }
    
private static voidput64bitsToArray(long value, byte[] dest, int offset)
puts an unsigned value in an array.

param
value The value to put.
param
dest the destination array
param
offset the offset in the array where to put the value. Array length must be at least offset + 8

        dest[offset + 7] = (byte)(value & 0x00000000000000FFL);
        dest[offset + 6] = (byte)((value & 0x000000000000FF00L) >> 8);
        dest[offset + 5] = (byte)((value & 0x0000000000FF0000L) >> 16);
        dest[offset + 4] = (byte)((value & 0x00000000FF000000L) >> 24);
        dest[offset + 3] = (byte)((value & 0x000000FF00000000L) >> 32);
        dest[offset + 2] = (byte)((value & 0x0000FF0000000000L) >> 40);
        dest[offset + 1] = (byte)((value & 0x00FF000000000000L) >> 48);
        dest[offset + 0] = (byte)((value & 0xFF00000000000000L) >> 56);
    
public booleantestValue(int index, java.lang.Object value, CompareMethod compareMethod)

        // do a quick easy check on the type.
        if (index == 0) {
            if ((value instanceof String) == false) {
                throw new InvalidTypeException();
            }
        } else if ((value instanceof Long) == false) {
            throw new InvalidTypeException();
        }
        
        switch (compareMethod) {
            case EQUAL_TO:
                if (index == 0) {
                    return processId.equals(value);
                } else {
                    return getValueAsLong(index) == ((Long)value).longValue();
                }
            case LESSER_THAN:
                return getValueAsLong(index) <= ((Long)value).longValue();
            case LESSER_THAN_STRICT:
                return getValueAsLong(index) < ((Long)value).longValue();
            case GREATER_THAN:
                return getValueAsLong(index) >= ((Long)value).longValue();
            case GREATER_THAN_STRICT:
                return getValueAsLong(index) > ((Long)value).longValue();
            case BIT_CHECK:
                return (getValueAsLong(index) & ((Long)value).longValue()) != 0;
        }

        throw new ArrayIndexOutOfBoundsException();