Loading core/java/android/app/ActivityThread.java +36 −28 Original line number Diff line number Diff line Loading @@ -533,8 +533,10 @@ public final class ActivityThread { private native void dumpGraphicsInfo(FileDescriptor fd); private class ApplicationThread extends ApplicationThreadNative { private static final String HEAP_FULL_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s"; private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s"; private static final String HEAP_FULL_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s"; private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s"; private static final String ONE_COUNT_COLUMN = "%21s %8d"; private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d"; private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s"; Loading Loading @@ -1039,34 +1041,36 @@ public final class ActivityThread { // otherwise, show human-readable format if (dumpFullInfo) { printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private", "Shared", "Private", "Heap", "Heap", "Heap"); "Shared", "Private", "Swapped", "Heap", "Heap", "Heap"); printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty", "Clean", "Clean", "Size", "Alloc", "Free"); "Clean", "Clean", "Dirty", "Size", "Alloc", "Free"); printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------", "------", "------", "------", "------", "------"); "------", "------", "------", "------", "------", "------"); printRow(pw, HEAP_FULL_COLUMN, "Native Heap", memInfo.nativePss, memInfo.nativeSwappablePss, memInfo.nativeSharedDirty, memInfo.nativePrivateDirty, memInfo.nativeSharedClean, memInfo.nativePrivateClean, nativeMax, nativeAllocated, nativeFree); memInfo.nativePrivateClean, memInfo.nativeSwappedOut, nativeMax, nativeAllocated, nativeFree); printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss, memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty, memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean, memInfo.dalvikPrivateClean, dalvikMax, dalvikAllocated, dalvikFree); memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut, dalvikMax, dalvikAllocated, dalvikFree); } else { printRow(pw, HEAP_COLUMN, "", "Pss", "Pss", "Private", "Private", "Heap", "Heap", "Heap"); printRow(pw, HEAP_COLUMN, "", "Total", "Clean", "Dirty", "Clean", "Size", "Alloc", "Free"); printRow(pw, HEAP_COLUMN, "", "Pss", "Private", "Private", "Swapped", "Heap", "Heap", "Heap"); printRow(pw, HEAP_COLUMN, "", "Total", "Dirty", "Clean", "Dirty", "Size", "Alloc", "Free"); printRow(pw, HEAP_COLUMN, "", "------", "------", "------", "------", "------", "------", "------"); "------", "------", "------", "------", "------"); printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss, memInfo.nativeSwappablePss, memInfo.nativePrivateDirty, memInfo.nativePrivateClean, nativeMax, nativeAllocated, nativeFree); memInfo.nativePrivateClean, memInfo.nativeSwappedOut, nativeMax, nativeAllocated, nativeFree); printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss, memInfo.dalvikSwappablePss, memInfo.dalvikPrivateDirty, memInfo.dalvikPrivateClean, dalvikMax, dalvikAllocated, dalvikFree); memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut, dalvikMax, dalvikAllocated, dalvikFree); } int otherPss = memInfo.otherPss; Loading @@ -1075,6 +1079,7 @@ public final class ActivityThread { int otherPrivateDirty = memInfo.otherPrivateDirty; int otherSharedClean = memInfo.otherSharedClean; int otherPrivateClean = memInfo.otherPrivateClean; int otherSwappedOut = memInfo.otherSwappedOut; for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) { final int myPss = memInfo.getOtherPss(i); Loading @@ -1083,16 +1088,17 @@ public final class ActivityThread { final int myPrivateDirty = memInfo.getOtherPrivateDirty(i); final int mySharedClean = memInfo.getOtherSharedClean(i); final int myPrivateClean = memInfo.getOtherPrivateClean(i); final int mySwappedOut = memInfo.getOtherSwappedOut(i); if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 || mySharedClean != 0 || myPrivateClean != 0) { || mySharedClean != 0 || myPrivateClean != 0 || mySwappedOut != 0) { if (dumpFullInfo) { printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i), myPss, mySwappablePss, mySharedDirty, myPrivateDirty, mySharedClean, myPrivateClean, "", "", ""); mySharedClean, myPrivateClean, mySwappedOut, "", "", ""); } else { printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), myPss, mySwappablePss, myPrivateDirty, myPrivateClean, "", "", ""); myPss, myPrivateDirty, myPrivateClean, mySwappedOut, "", "", ""); } otherPss -= myPss; otherSwappablePss -= mySwappablePss; Loading @@ -1100,27 +1106,28 @@ public final class ActivityThread { otherPrivateDirty -= myPrivateDirty; otherSharedClean -= mySharedClean; otherPrivateClean -= myPrivateClean; otherSwappedOut -= mySwappedOut; } } if (dumpFullInfo) { printRow(pw, HEAP_FULL_COLUMN, "Unknown", otherPss, otherSwappablePss, otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean, "", "", ""); otherSwappedOut, "", "", ""); printRow(pw, HEAP_FULL_COLUMN, "TOTAL", memInfo.getTotalPss(), memInfo.getTotalSwappablePss(), memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(), memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(), nativeMax+dalvikMax, memInfo.getTotalSwappedOut(), nativeMax+dalvikMax, nativeAllocated+dalvikAllocated, nativeFree+dalvikFree); } else { printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSwappablePss, otherPrivateDirty, otherPrivateClean, printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherPrivateDirty, otherPrivateClean, otherSwappedOut, "", "", ""); printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(), memInfo.getTotalSwappablePss(), memInfo.getTotalPrivateDirty(), memInfo.getTotalPrivateClean(), memInfo.getTotalSwappedOut(), nativeMax+dalvikMax, nativeAllocated+dalvikAllocated, nativeFree+dalvikFree); } Loading @@ -1137,16 +1144,17 @@ public final class ActivityThread { final int myPrivateDirty = memInfo.getOtherPrivateDirty(i); final int mySharedClean = memInfo.getOtherSharedClean(i); final int myPrivateClean = memInfo.getOtherPrivateClean(i); final int mySwappedOut = memInfo.getOtherSwappedOut(i); if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 || mySharedClean != 0 || myPrivateClean != 0) { if (dumpFullInfo) { printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i), myPss, mySwappablePss, mySharedDirty, myPrivateDirty, mySharedClean, myPrivateClean, "", "", ""); mySharedClean, myPrivateClean, mySwappedOut, "", "", ""); } else { printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), myPss, mySwappablePss, myPrivateDirty, myPrivateClean, "", "", ""); myPss, myPrivateDirty, myPrivateClean, mySwappedOut, "", "", ""); } } } Loading core/java/android/os/Debug.java +32 −4 Original line number Diff line number Diff line Loading @@ -124,6 +124,9 @@ public final class Debug /** The shared clean pages used by dalvik heap. */ /** @hide We may want to expose this, eventually. */ public int dalvikSharedClean; /** The dirty dalvik pages that have been swapped out. */ /** @hide We may want to expose this, eventually. */ public int dalvikSwappedOut; /** The proportional set size for the native heap. */ public int nativePss; Loading @@ -140,6 +143,9 @@ public final class Debug /** The shared clean pages used by the native heap. */ /** @hide We may want to expose this, eventually. */ public int nativeSharedClean; /** The dirty native pages that have been swapped out. */ /** @hide We may want to expose this, eventually. */ public int nativeSwappedOut; /** The proportional set size for everything else. */ public int otherPss; Loading @@ -156,6 +162,9 @@ public final class Debug /** The shared clean pages used by everything else. */ /** @hide We may want to expose this, eventually. */ public int otherSharedClean; /** The dirty pages used by anyting else that have been swapped out. */ /** @hide We may want to expose this, eventually. */ public int otherSwappedOut; /** @hide */ public static final int NUM_OTHER_STATS = 16; Loading @@ -164,7 +173,7 @@ public final class Debug public static final int NUM_DVK_STATS = 5; /** @hide */ public static final int NUM_CATEGORIES = 6; public static final int NUM_CATEGORIES = 7; /** @hide */ public static final int offsetPss = 0; Loading @@ -178,7 +187,8 @@ public final class Debug public static final int offsetPrivateClean = 4; /** @hide */ public static final int offsetSharedClean = 5; /** @hide */ public static final int offsetSwappedOut = 6; private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES]; Loading Loading @@ -236,6 +246,14 @@ public final class Debug return dalvikSharedClean + nativeSharedClean + otherSharedClean; } /** * Return total swapped out memory in kB. * @hide */ public int getTotalSwappedOut() { return dalvikSwappedOut + nativeSwappedOut + otherSwappedOut; } /** @hide */ public int getOtherPss(int which) { return otherStats[which*NUM_CATEGORIES + offsetPss]; Loading Loading @@ -263,12 +281,16 @@ public final class Debug return otherStats[which*NUM_CATEGORIES + offsetPrivateClean]; } /** @hide */ public int getOtherSharedClean(int which) { return otherStats[which*NUM_CATEGORIES + offsetSharedClean]; } /** @hide */ public int getOtherSwappedOut(int which) { return otherStats[which*NUM_CATEGORIES + offsetSwappedOut]; } /** @hide */ public static String getOtherLabel(int which) { switch (which) { Loading @@ -287,7 +309,7 @@ public final class Debug case 12: return "Other mmap"; case 13: return "Graphics"; case 14: return "GL"; case 15: return "Other memtrack"; case 15: return "Memtrack"; case 16: return ".Heap"; case 17: return ".LOS"; case 18: return ".LinearAlloc"; Loading @@ -308,18 +330,21 @@ public final class Debug dest.writeInt(dalvikSharedDirty); dest.writeInt(dalvikPrivateClean); dest.writeInt(dalvikSharedClean); dest.writeInt(dalvikSwappedOut); dest.writeInt(nativePss); dest.writeInt(nativeSwappablePss); dest.writeInt(nativePrivateDirty); dest.writeInt(nativeSharedDirty); dest.writeInt(nativePrivateClean); dest.writeInt(nativeSharedClean); dest.writeInt(nativeSwappedOut); dest.writeInt(otherPss); dest.writeInt(otherSwappablePss); dest.writeInt(otherPrivateDirty); dest.writeInt(otherSharedDirty); dest.writeInt(otherPrivateClean); dest.writeInt(otherSharedClean); dest.writeInt(otherSwappedOut); dest.writeIntArray(otherStats); } Loading @@ -330,18 +355,21 @@ public final class Debug dalvikSharedDirty = source.readInt(); dalvikPrivateClean = source.readInt(); dalvikSharedClean = source.readInt(); dalvikSwappedOut = source.readInt(); nativePss = source.readInt(); nativeSwappablePss = source.readInt(); nativePrivateDirty = source.readInt(); nativeSharedDirty = source.readInt(); nativePrivateClean = source.readInt(); nativeSharedClean = source.readInt(); nativeSwappedOut = source.readInt(); otherPss = source.readInt(); otherSwappablePss = source.readInt(); otherPrivateDirty = source.readInt(); otherSharedDirty = source.readInt(); otherPrivateClean = source.readInt(); otherSharedClean = source.readInt(); otherSwappedOut = source.readInt(); otherStats = source.createIntArray(); } Loading core/jni/android_os_Debug.cpp +35 −12 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ struct stat_fields { jfieldID sharedDirty_field; jfieldID privateClean_field; jfieldID sharedClean_field; jfieldID swappedOut_field; }; struct stat_field_names { Loading @@ -89,14 +90,18 @@ struct stat_field_names { const char* sharedDirty_name; const char* privateClean_name; const char* sharedClean_name; const char* swappedOut_name; }; static stat_fields stat_fields[_NUM_CORE_HEAP]; static stat_field_names stat_field_names[_NUM_CORE_HEAP] = { { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty", "otherPrivateClean", "otherSharedClean" }, { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty", "dalvikPrivateClean", "dalvikSharedClean" }, { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty", "nativePrivateClean", "nativeSharedClean" } { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty", "otherPrivateClean", "otherSharedClean", "otherSwappedOut" }, { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty", "dalvikPrivateClean", "dalvikSharedClean", "dalvikSwappedOut" }, { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty", "nativePrivateClean", "nativeSharedClean", "nativeSwappedOut" } }; jfieldID otherStats_field; Loading @@ -110,6 +115,7 @@ struct stats_t { int sharedDirty; int privateClean; int sharedClean; int swappedOut; }; #define BINDER_STATS "/proc/binder/stats" Loading Loading @@ -219,6 +225,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats) float sharing_proportion = 0.0; unsigned shared_clean = 0, shared_dirty = 0; unsigned private_clean = 0, private_dirty = 0; unsigned swapped_out = 0; bool is_swappable = false; unsigned referenced = 0; unsigned temp; Loading Loading @@ -333,28 +340,36 @@ static void read_mapinfo(FILE *fp, stats_t* stats) //ALOGI("native=%d dalvik=%d sqlite=%d: %s\n", isNativeHeap, isDalvikHeap, // isSqliteHeap, line); shared_clean = 0; shared_dirty = 0; private_clean = 0; private_dirty = 0; swapped_out = 0; while (true) { if (fgets(line, 1024, fp) == 0) { done = true; break; } if (sscanf(line, "Size: %d kB", &temp) == 1) { if (line[0] == 'S' && sscanf(line, "Size: %d kB", &temp) == 1) { size = temp; } else if (sscanf(line, "Rss: %d kB", &temp) == 1) { } else if (line[0] == 'R' && sscanf(line, "Rss: %d kB", &temp) == 1) { resident = temp; } else if (sscanf(line, "Pss: %d kB", &temp) == 1) { } else if (line[0] == 'P' && sscanf(line, "Pss: %d kB", &temp) == 1) { pss = temp; } else if (sscanf(line, "Shared_Clean: %d kB", &temp) == 1) { } else if (line[0] == 'S' && sscanf(line, "Shared_Clean: %d kB", &temp) == 1) { shared_clean = temp; } else if (sscanf(line, "Shared_Dirty: %d kB", &temp) == 1) { } else if (line[0] == 'S' && sscanf(line, "Shared_Dirty: %d kB", &temp) == 1) { shared_dirty = temp; } else if (sscanf(line, "Private_Clean: %d kB", &temp) == 1) { } else if (line[0] == 'P' && sscanf(line, "Private_Clean: %d kB", &temp) == 1) { private_clean = temp; } else if (sscanf(line, "Private_Dirty: %d kB", &temp) == 1) { } else if (line[0] == 'P' && sscanf(line, "Private_Dirty: %d kB", &temp) == 1) { private_dirty = temp; } else if (sscanf(line, "Referenced: %d kB", &temp) == 1) { } else if (line[0] == 'R' && sscanf(line, "Referenced: %d kB", &temp) == 1) { referenced = temp; } else if (line[0] == 'S' && sscanf(line, "Swap: %d kB", &temp) == 1) { swapped_out = temp; } else if (strlen(line) > 30 && line[8] == '-' && line[17] == ' ') { // looks like a new mapping // example: "10000000-10001000 ---p 10000000 00:00 0" Loading @@ -366,7 +381,8 @@ static void read_mapinfo(FILE *fp, stats_t* stats) if (is_swappable && (pss > 0)) { sharing_proportion = 0.0; if ((shared_clean > 0) || (shared_dirty > 0)) { sharing_proportion = (pss - private_clean - private_dirty)/(shared_clean+shared_dirty); sharing_proportion = (pss - private_clean - private_dirty)/(shared_clean+shared_dirty); } swappable_pss = (sharing_proportion*shared_clean) + private_clean; } else Loading @@ -378,6 +394,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats) stats[whichHeap].sharedDirty += shared_dirty; stats[whichHeap].privateClean += private_clean; stats[whichHeap].sharedClean += shared_clean; stats[whichHeap].swappedOut += swapped_out; if (whichHeap == HEAP_DALVIK || whichHeap == HEAP_DALVIK_OTHER) { stats[subHeap].pss += pss; stats[subHeap].swappablePss += swappable_pss; Loading @@ -385,6 +402,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats) stats[subHeap].sharedDirty += shared_dirty; stats[subHeap].privateClean += private_clean; stats[subHeap].sharedClean += shared_clean; stats[subHeap].swappedOut += swapped_out; } } } Loading Loading @@ -428,6 +446,7 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty; stats[HEAP_UNKNOWN].privateClean += stats[i].privateClean; stats[HEAP_UNKNOWN].sharedClean += stats[i].sharedClean; stats[HEAP_UNKNOWN].swappedOut += stats[i].swappedOut; } for (int i=0; i<_NUM_CORE_HEAP; i++) { Loading @@ -437,6 +456,7 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty); env->SetIntField(object, stat_fields[i].privateClean_field, stats[i].privateClean); env->SetIntField(object, stat_fields[i].sharedClean_field, stats[i].sharedClean); env->SetIntField(object, stat_fields[i].swappedOut_field, stats[i].swappedOut); } Loading @@ -455,6 +475,7 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, otherArray[j++] = stats[i].sharedDirty; otherArray[j++] = stats[i].privateClean; otherArray[j++] = stats[i].sharedClean; otherArray[j++] = stats[i].swappedOut; } env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0); Loading Loading @@ -971,6 +992,8 @@ int register_android_os_Debug(JNIEnv *env) env->GetFieldID(clazz, stat_field_names[i].privateClean_name, "I"); stat_fields[i].sharedClean_field = env->GetFieldID(clazz, stat_field_names[i].sharedClean_name, "I"); stat_fields[i].swappedOut_field = env->GetFieldID(clazz, stat_field_names[i].swappedOut_name, "I"); } return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods)); Loading Loading
core/java/android/app/ActivityThread.java +36 −28 Original line number Diff line number Diff line Loading @@ -533,8 +533,10 @@ public final class ActivityThread { private native void dumpGraphicsInfo(FileDescriptor fd); private class ApplicationThread extends ApplicationThreadNative { private static final String HEAP_FULL_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s"; private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s"; private static final String HEAP_FULL_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s"; private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s"; private static final String ONE_COUNT_COLUMN = "%21s %8d"; private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d"; private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s"; Loading Loading @@ -1039,34 +1041,36 @@ public final class ActivityThread { // otherwise, show human-readable format if (dumpFullInfo) { printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private", "Shared", "Private", "Heap", "Heap", "Heap"); "Shared", "Private", "Swapped", "Heap", "Heap", "Heap"); printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty", "Clean", "Clean", "Size", "Alloc", "Free"); "Clean", "Clean", "Dirty", "Size", "Alloc", "Free"); printRow(pw, HEAP_FULL_COLUMN, "", "------", "------", "------", "------", "------", "------", "------", "------", "------"); "------", "------", "------", "------", "------", "------"); printRow(pw, HEAP_FULL_COLUMN, "Native Heap", memInfo.nativePss, memInfo.nativeSwappablePss, memInfo.nativeSharedDirty, memInfo.nativePrivateDirty, memInfo.nativeSharedClean, memInfo.nativePrivateClean, nativeMax, nativeAllocated, nativeFree); memInfo.nativePrivateClean, memInfo.nativeSwappedOut, nativeMax, nativeAllocated, nativeFree); printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss, memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty, memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean, memInfo.dalvikPrivateClean, dalvikMax, dalvikAllocated, dalvikFree); memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut, dalvikMax, dalvikAllocated, dalvikFree); } else { printRow(pw, HEAP_COLUMN, "", "Pss", "Pss", "Private", "Private", "Heap", "Heap", "Heap"); printRow(pw, HEAP_COLUMN, "", "Total", "Clean", "Dirty", "Clean", "Size", "Alloc", "Free"); printRow(pw, HEAP_COLUMN, "", "Pss", "Private", "Private", "Swapped", "Heap", "Heap", "Heap"); printRow(pw, HEAP_COLUMN, "", "Total", "Dirty", "Clean", "Dirty", "Size", "Alloc", "Free"); printRow(pw, HEAP_COLUMN, "", "------", "------", "------", "------", "------", "------", "------"); "------", "------", "------", "------", "------"); printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss, memInfo.nativeSwappablePss, memInfo.nativePrivateDirty, memInfo.nativePrivateClean, nativeMax, nativeAllocated, nativeFree); memInfo.nativePrivateClean, memInfo.nativeSwappedOut, nativeMax, nativeAllocated, nativeFree); printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss, memInfo.dalvikSwappablePss, memInfo.dalvikPrivateDirty, memInfo.dalvikPrivateClean, dalvikMax, dalvikAllocated, dalvikFree); memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut, dalvikMax, dalvikAllocated, dalvikFree); } int otherPss = memInfo.otherPss; Loading @@ -1075,6 +1079,7 @@ public final class ActivityThread { int otherPrivateDirty = memInfo.otherPrivateDirty; int otherSharedClean = memInfo.otherSharedClean; int otherPrivateClean = memInfo.otherPrivateClean; int otherSwappedOut = memInfo.otherSwappedOut; for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) { final int myPss = memInfo.getOtherPss(i); Loading @@ -1083,16 +1088,17 @@ public final class ActivityThread { final int myPrivateDirty = memInfo.getOtherPrivateDirty(i); final int mySharedClean = memInfo.getOtherSharedClean(i); final int myPrivateClean = memInfo.getOtherPrivateClean(i); final int mySwappedOut = memInfo.getOtherSwappedOut(i); if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 || mySharedClean != 0 || myPrivateClean != 0) { || mySharedClean != 0 || myPrivateClean != 0 || mySwappedOut != 0) { if (dumpFullInfo) { printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i), myPss, mySwappablePss, mySharedDirty, myPrivateDirty, mySharedClean, myPrivateClean, "", "", ""); mySharedClean, myPrivateClean, mySwappedOut, "", "", ""); } else { printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), myPss, mySwappablePss, myPrivateDirty, myPrivateClean, "", "", ""); myPss, myPrivateDirty, myPrivateClean, mySwappedOut, "", "", ""); } otherPss -= myPss; otherSwappablePss -= mySwappablePss; Loading @@ -1100,27 +1106,28 @@ public final class ActivityThread { otherPrivateDirty -= myPrivateDirty; otherSharedClean -= mySharedClean; otherPrivateClean -= myPrivateClean; otherSwappedOut -= mySwappedOut; } } if (dumpFullInfo) { printRow(pw, HEAP_FULL_COLUMN, "Unknown", otherPss, otherSwappablePss, otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean, "", "", ""); otherSwappedOut, "", "", ""); printRow(pw, HEAP_FULL_COLUMN, "TOTAL", memInfo.getTotalPss(), memInfo.getTotalSwappablePss(), memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(), memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(), nativeMax+dalvikMax, memInfo.getTotalSwappedOut(), nativeMax+dalvikMax, nativeAllocated+dalvikAllocated, nativeFree+dalvikFree); } else { printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSwappablePss, otherPrivateDirty, otherPrivateClean, printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherPrivateDirty, otherPrivateClean, otherSwappedOut, "", "", ""); printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(), memInfo.getTotalSwappablePss(), memInfo.getTotalPrivateDirty(), memInfo.getTotalPrivateClean(), memInfo.getTotalSwappedOut(), nativeMax+dalvikMax, nativeAllocated+dalvikAllocated, nativeFree+dalvikFree); } Loading @@ -1137,16 +1144,17 @@ public final class ActivityThread { final int myPrivateDirty = memInfo.getOtherPrivateDirty(i); final int mySharedClean = memInfo.getOtherSharedClean(i); final int myPrivateClean = memInfo.getOtherPrivateClean(i); final int mySwappedOut = memInfo.getOtherSwappedOut(i); if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 || mySharedClean != 0 || myPrivateClean != 0) { if (dumpFullInfo) { printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i), myPss, mySwappablePss, mySharedDirty, myPrivateDirty, mySharedClean, myPrivateClean, "", "", ""); mySharedClean, myPrivateClean, mySwappedOut, "", "", ""); } else { printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), myPss, mySwappablePss, myPrivateDirty, myPrivateClean, "", "", ""); myPss, myPrivateDirty, myPrivateClean, mySwappedOut, "", "", ""); } } } Loading
core/java/android/os/Debug.java +32 −4 Original line number Diff line number Diff line Loading @@ -124,6 +124,9 @@ public final class Debug /** The shared clean pages used by dalvik heap. */ /** @hide We may want to expose this, eventually. */ public int dalvikSharedClean; /** The dirty dalvik pages that have been swapped out. */ /** @hide We may want to expose this, eventually. */ public int dalvikSwappedOut; /** The proportional set size for the native heap. */ public int nativePss; Loading @@ -140,6 +143,9 @@ public final class Debug /** The shared clean pages used by the native heap. */ /** @hide We may want to expose this, eventually. */ public int nativeSharedClean; /** The dirty native pages that have been swapped out. */ /** @hide We may want to expose this, eventually. */ public int nativeSwappedOut; /** The proportional set size for everything else. */ public int otherPss; Loading @@ -156,6 +162,9 @@ public final class Debug /** The shared clean pages used by everything else. */ /** @hide We may want to expose this, eventually. */ public int otherSharedClean; /** The dirty pages used by anyting else that have been swapped out. */ /** @hide We may want to expose this, eventually. */ public int otherSwappedOut; /** @hide */ public static final int NUM_OTHER_STATS = 16; Loading @@ -164,7 +173,7 @@ public final class Debug public static final int NUM_DVK_STATS = 5; /** @hide */ public static final int NUM_CATEGORIES = 6; public static final int NUM_CATEGORIES = 7; /** @hide */ public static final int offsetPss = 0; Loading @@ -178,7 +187,8 @@ public final class Debug public static final int offsetPrivateClean = 4; /** @hide */ public static final int offsetSharedClean = 5; /** @hide */ public static final int offsetSwappedOut = 6; private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES]; Loading Loading @@ -236,6 +246,14 @@ public final class Debug return dalvikSharedClean + nativeSharedClean + otherSharedClean; } /** * Return total swapped out memory in kB. * @hide */ public int getTotalSwappedOut() { return dalvikSwappedOut + nativeSwappedOut + otherSwappedOut; } /** @hide */ public int getOtherPss(int which) { return otherStats[which*NUM_CATEGORIES + offsetPss]; Loading Loading @@ -263,12 +281,16 @@ public final class Debug return otherStats[which*NUM_CATEGORIES + offsetPrivateClean]; } /** @hide */ public int getOtherSharedClean(int which) { return otherStats[which*NUM_CATEGORIES + offsetSharedClean]; } /** @hide */ public int getOtherSwappedOut(int which) { return otherStats[which*NUM_CATEGORIES + offsetSwappedOut]; } /** @hide */ public static String getOtherLabel(int which) { switch (which) { Loading @@ -287,7 +309,7 @@ public final class Debug case 12: return "Other mmap"; case 13: return "Graphics"; case 14: return "GL"; case 15: return "Other memtrack"; case 15: return "Memtrack"; case 16: return ".Heap"; case 17: return ".LOS"; case 18: return ".LinearAlloc"; Loading @@ -308,18 +330,21 @@ public final class Debug dest.writeInt(dalvikSharedDirty); dest.writeInt(dalvikPrivateClean); dest.writeInt(dalvikSharedClean); dest.writeInt(dalvikSwappedOut); dest.writeInt(nativePss); dest.writeInt(nativeSwappablePss); dest.writeInt(nativePrivateDirty); dest.writeInt(nativeSharedDirty); dest.writeInt(nativePrivateClean); dest.writeInt(nativeSharedClean); dest.writeInt(nativeSwappedOut); dest.writeInt(otherPss); dest.writeInt(otherSwappablePss); dest.writeInt(otherPrivateDirty); dest.writeInt(otherSharedDirty); dest.writeInt(otherPrivateClean); dest.writeInt(otherSharedClean); dest.writeInt(otherSwappedOut); dest.writeIntArray(otherStats); } Loading @@ -330,18 +355,21 @@ public final class Debug dalvikSharedDirty = source.readInt(); dalvikPrivateClean = source.readInt(); dalvikSharedClean = source.readInt(); dalvikSwappedOut = source.readInt(); nativePss = source.readInt(); nativeSwappablePss = source.readInt(); nativePrivateDirty = source.readInt(); nativeSharedDirty = source.readInt(); nativePrivateClean = source.readInt(); nativeSharedClean = source.readInt(); nativeSwappedOut = source.readInt(); otherPss = source.readInt(); otherSwappablePss = source.readInt(); otherPrivateDirty = source.readInt(); otherSharedDirty = source.readInt(); otherPrivateClean = source.readInt(); otherSharedClean = source.readInt(); otherSwappedOut = source.readInt(); otherStats = source.createIntArray(); } Loading
core/jni/android_os_Debug.cpp +35 −12 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ struct stat_fields { jfieldID sharedDirty_field; jfieldID privateClean_field; jfieldID sharedClean_field; jfieldID swappedOut_field; }; struct stat_field_names { Loading @@ -89,14 +90,18 @@ struct stat_field_names { const char* sharedDirty_name; const char* privateClean_name; const char* sharedClean_name; const char* swappedOut_name; }; static stat_fields stat_fields[_NUM_CORE_HEAP]; static stat_field_names stat_field_names[_NUM_CORE_HEAP] = { { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty", "otherPrivateClean", "otherSharedClean" }, { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty", "dalvikPrivateClean", "dalvikSharedClean" }, { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty", "nativePrivateClean", "nativeSharedClean" } { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty", "otherPrivateClean", "otherSharedClean", "otherSwappedOut" }, { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty", "dalvikPrivateClean", "dalvikSharedClean", "dalvikSwappedOut" }, { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty", "nativePrivateClean", "nativeSharedClean", "nativeSwappedOut" } }; jfieldID otherStats_field; Loading @@ -110,6 +115,7 @@ struct stats_t { int sharedDirty; int privateClean; int sharedClean; int swappedOut; }; #define BINDER_STATS "/proc/binder/stats" Loading Loading @@ -219,6 +225,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats) float sharing_proportion = 0.0; unsigned shared_clean = 0, shared_dirty = 0; unsigned private_clean = 0, private_dirty = 0; unsigned swapped_out = 0; bool is_swappable = false; unsigned referenced = 0; unsigned temp; Loading Loading @@ -333,28 +340,36 @@ static void read_mapinfo(FILE *fp, stats_t* stats) //ALOGI("native=%d dalvik=%d sqlite=%d: %s\n", isNativeHeap, isDalvikHeap, // isSqliteHeap, line); shared_clean = 0; shared_dirty = 0; private_clean = 0; private_dirty = 0; swapped_out = 0; while (true) { if (fgets(line, 1024, fp) == 0) { done = true; break; } if (sscanf(line, "Size: %d kB", &temp) == 1) { if (line[0] == 'S' && sscanf(line, "Size: %d kB", &temp) == 1) { size = temp; } else if (sscanf(line, "Rss: %d kB", &temp) == 1) { } else if (line[0] == 'R' && sscanf(line, "Rss: %d kB", &temp) == 1) { resident = temp; } else if (sscanf(line, "Pss: %d kB", &temp) == 1) { } else if (line[0] == 'P' && sscanf(line, "Pss: %d kB", &temp) == 1) { pss = temp; } else if (sscanf(line, "Shared_Clean: %d kB", &temp) == 1) { } else if (line[0] == 'S' && sscanf(line, "Shared_Clean: %d kB", &temp) == 1) { shared_clean = temp; } else if (sscanf(line, "Shared_Dirty: %d kB", &temp) == 1) { } else if (line[0] == 'S' && sscanf(line, "Shared_Dirty: %d kB", &temp) == 1) { shared_dirty = temp; } else if (sscanf(line, "Private_Clean: %d kB", &temp) == 1) { } else if (line[0] == 'P' && sscanf(line, "Private_Clean: %d kB", &temp) == 1) { private_clean = temp; } else if (sscanf(line, "Private_Dirty: %d kB", &temp) == 1) { } else if (line[0] == 'P' && sscanf(line, "Private_Dirty: %d kB", &temp) == 1) { private_dirty = temp; } else if (sscanf(line, "Referenced: %d kB", &temp) == 1) { } else if (line[0] == 'R' && sscanf(line, "Referenced: %d kB", &temp) == 1) { referenced = temp; } else if (line[0] == 'S' && sscanf(line, "Swap: %d kB", &temp) == 1) { swapped_out = temp; } else if (strlen(line) > 30 && line[8] == '-' && line[17] == ' ') { // looks like a new mapping // example: "10000000-10001000 ---p 10000000 00:00 0" Loading @@ -366,7 +381,8 @@ static void read_mapinfo(FILE *fp, stats_t* stats) if (is_swappable && (pss > 0)) { sharing_proportion = 0.0; if ((shared_clean > 0) || (shared_dirty > 0)) { sharing_proportion = (pss - private_clean - private_dirty)/(shared_clean+shared_dirty); sharing_proportion = (pss - private_clean - private_dirty)/(shared_clean+shared_dirty); } swappable_pss = (sharing_proportion*shared_clean) + private_clean; } else Loading @@ -378,6 +394,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats) stats[whichHeap].sharedDirty += shared_dirty; stats[whichHeap].privateClean += private_clean; stats[whichHeap].sharedClean += shared_clean; stats[whichHeap].swappedOut += swapped_out; if (whichHeap == HEAP_DALVIK || whichHeap == HEAP_DALVIK_OTHER) { stats[subHeap].pss += pss; stats[subHeap].swappablePss += swappable_pss; Loading @@ -385,6 +402,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats) stats[subHeap].sharedDirty += shared_dirty; stats[subHeap].privateClean += private_clean; stats[subHeap].sharedClean += shared_clean; stats[subHeap].swappedOut += swapped_out; } } } Loading Loading @@ -428,6 +446,7 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty; stats[HEAP_UNKNOWN].privateClean += stats[i].privateClean; stats[HEAP_UNKNOWN].sharedClean += stats[i].sharedClean; stats[HEAP_UNKNOWN].swappedOut += stats[i].swappedOut; } for (int i=0; i<_NUM_CORE_HEAP; i++) { Loading @@ -437,6 +456,7 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty); env->SetIntField(object, stat_fields[i].privateClean_field, stats[i].privateClean); env->SetIntField(object, stat_fields[i].sharedClean_field, stats[i].sharedClean); env->SetIntField(object, stat_fields[i].swappedOut_field, stats[i].swappedOut); } Loading @@ -455,6 +475,7 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, otherArray[j++] = stats[i].sharedDirty; otherArray[j++] = stats[i].privateClean; otherArray[j++] = stats[i].sharedClean; otherArray[j++] = stats[i].swappedOut; } env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0); Loading Loading @@ -971,6 +992,8 @@ int register_android_os_Debug(JNIEnv *env) env->GetFieldID(clazz, stat_field_names[i].privateClean_name, "I"); stat_fields[i].sharedClean_field = env->GetFieldID(clazz, stat_field_names[i].sharedClean_name, "I"); stat_fields[i].swappedOut_field = env->GetFieldID(clazz, stat_field_names[i].swappedOut_name, "I"); } return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods)); Loading