diff options
| -rw-r--r-- | api/current.txt | 7 | ||||
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 76 | ||||
| -rw-r--r-- | core/java/android/os/Debug.java | 97 | ||||
| -rw-r--r-- | core/jni/android_os_Debug.cpp | 93 |
4 files changed, 237 insertions, 36 deletions
diff --git a/api/current.txt b/api/current.txt index 3685cf4a6ffd..96a8481c48c5 100644 --- a/api/current.txt +++ b/api/current.txt @@ -17065,28 +17065,29 @@ package android.os { ctor public Debug.MemoryInfo(); method public int describeContents(); method public static java.lang.String getOtherLabel(int); + method public int getOtherPrivateClean(int); method public int getOtherPrivateDirty(int); method public int getOtherPss(int); method public int getOtherSharedClean(int); method public int getOtherSharedDirty(int); + method public int getOtherSwappablePss(int); + method public int getTotalPrivateClean(); method public int getTotalPrivateDirty(); method public int getTotalPss(); method public int getTotalSharedClean(); method public int getTotalSharedDirty(); + method public int getTotalSwappablePss(); method public void readFromParcel(android.os.Parcel); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; field public int dalvikPrivateDirty; field public int dalvikPss; - field public int dalvikSharedClean; field public int dalvikSharedDirty; field public int nativePrivateDirty; field public int nativePss; - field public int nativeSharedClean; field public int nativeSharedDirty; field public int otherPrivateDirty; field public int otherPss; - field public int otherSharedClean; field public int otherSharedDirty; } diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 82ecfa366c03..d1bf0af1f407 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -543,13 +543,13 @@ public final class ActivityThread { private native void dumpGraphicsInfo(FileDescriptor fd); private class ApplicationThread extends ApplicationThreadNative { - private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s"; + private static final String HEAP_COLUMN = "%13s %8s %8s %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"; // Formatting for checkin service - update version if row format changes - private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1; + private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 2; private void updatePendingConfiguration(Configuration config) { synchronized (mPackages) { @@ -970,6 +970,12 @@ public final class ActivityThread { pw.print(memInfo.otherPss); pw.print(','); pw.print(memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss); pw.print(','); + // Heap info - proportional set size + pw.print(memInfo.nativeSwappablePss); pw.print(','); + pw.print(memInfo.dalvikSwappablePss); pw.print(','); + pw.print(memInfo.otherSwappablePss); pw.print(','); + pw.print(memInfo.nativeSwappablePss + memInfo.dalvikSwappablePss + memInfo.otherSwappablePss); pw.print(','); + // Heap info - shared dirty pw.print(memInfo.nativeSharedDirty); pw.print(','); pw.print(memInfo.dalvikSharedDirty); pw.print(','); @@ -984,7 +990,7 @@ public final class ActivityThread { pw.print(memInfo.nativeSharedClean + memInfo.dalvikSharedClean + memInfo.otherSharedClean); pw.print(','); - // Heap info - private + // Heap info - private Dirty pw.print(memInfo.nativePrivateDirty); pw.print(','); pw.print(memInfo.dalvikPrivateDirty); pw.print(','); pw.print(memInfo.otherPrivateDirty); pw.print(','); @@ -992,6 +998,14 @@ public final class ActivityThread { + memInfo.otherPrivateDirty); pw.print(','); + // Heap info - private Clean + pw.print(memInfo.nativePrivateClean); pw.print(','); + pw.print(memInfo.dalvikPrivateClean); pw.print(','); + pw.print(memInfo.otherPrivateClean); pw.print(','); + pw.print(memInfo.nativePrivateClean + memInfo.dalvikPrivateClean + + memInfo.otherPrivateClean); pw.print(','); + + // Object counts pw.print(viewInstanceCount); pw.print(','); pw.print(viewRootInstanceCount); pw.print(','); @@ -1026,36 +1040,62 @@ public final class ActivityThread { } // otherwise, show human-readable format - printRow(pw, HEAP_COLUMN, "", "", "Shared", "Private", "Shared", "Heap", "Heap", "Heap"); - printRow(pw, HEAP_COLUMN, "", "Pss", "Dirty", "Dirty", "Clean", "Size", "Alloc", "Free"); - printRow(pw, HEAP_COLUMN, "", "------", "------", "------", "------", "------", "------", + printRow(pw, HEAP_COLUMN, "", "", "Swapable","Shared", "Private", "Shared", "Private", "Heap", "Heap", "Heap"); + printRow(pw, HEAP_COLUMN, "", "Pss", "Pss", "Dirty", "Dirty", "Clean", "Clean", "Size", "Alloc", "Free"); + printRow(pw, HEAP_COLUMN, "", "------", "------", "------", "------", "------", "------", "------", "------", "------"); - printRow(pw, HEAP_COLUMN, "Native", memInfo.nativePss, memInfo.nativeSharedDirty, - memInfo.nativePrivateDirty, memInfo.nativeSharedClean, nativeMax, nativeAllocated, nativeFree); - printRow(pw, HEAP_COLUMN, "Dalvik", memInfo.dalvikPss, memInfo.dalvikSharedDirty, - memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean, dalvikMax, dalvikAllocated, dalvikFree); + printRow(pw, HEAP_COLUMN, "Native", memInfo.nativePss, memInfo.nativeSwappablePss, memInfo.nativeSharedDirty, + memInfo.nativePrivateDirty, memInfo.nativeSharedClean, memInfo.nativePrivateClean,nativeMax, + nativeAllocated, nativeFree); + printRow(pw, HEAP_COLUMN, "Dalvik", memInfo.dalvikPss, memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty, + memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean, memInfo.dalvikPrivateClean, dalvikMax, dalvikAllocated, + dalvikFree); int otherPss = memInfo.otherPss; + int otherSwappablePss = memInfo.otherSwappablePss; int otherSharedDirty = memInfo.otherSharedDirty; int otherPrivateDirty = memInfo.otherPrivateDirty; int otherSharedClean = memInfo.otherSharedClean; + int otherPrivateClean = memInfo.otherPrivateClean; for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) { printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), - memInfo.getOtherPss(i), memInfo.getOtherSharedDirty(i), - memInfo.getOtherPrivateDirty(i), memInfo.getOtherSharedClean(i), "", "", ""); + memInfo.getOtherPss(i), memInfo.getOtherSwappablePss(i), memInfo.getOtherSharedDirty(i), + memInfo.getOtherPrivateDirty(i), memInfo.getOtherSharedClean(i), memInfo.getOtherPrivateClean(i), + "", "", ""); otherPss -= memInfo.getOtherPss(i); + otherSwappablePss -= memInfo.getOtherSwappablePss(i); otherSharedDirty -= memInfo.getOtherSharedDirty(i); otherPrivateDirty -= memInfo.getOtherPrivateDirty(i); otherSharedClean -= memInfo.getOtherSharedClean(i); + otherPrivateClean -= memInfo.getOtherPrivateClean(i); } - printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSharedDirty, - otherPrivateDirty, otherSharedClean, "", "", ""); - printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(), - memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(), - memInfo.getTotalSharedClean(), nativeMax+dalvikMax, - nativeAllocated+dalvikAllocated, nativeFree+dalvikFree); + + + printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSwappablePss, otherSharedDirty, + otherPrivateDirty, otherSharedClean, otherPrivateClean,"", "", ""); + printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(), memInfo.getTotalSwappablePss(), + memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(), + memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(), nativeMax+dalvikMax, + nativeAllocated+dalvikAllocated, nativeFree+dalvikFree); + + pw.println(" "); + pw.println(" Dalvik"); + + for (int i=Debug.MemoryInfo.NUM_OTHER_STATS; + i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) { + printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), + memInfo.getOtherPss(i), memInfo.getOtherSwappablePss(i), memInfo.getOtherSharedDirty(i), + memInfo.getOtherPrivateDirty(i), memInfo.getOtherSharedClean(i), + memInfo.getOtherPrivateClean(i), "", "", ""); + otherPss -= memInfo.getOtherPss(i); + otherSwappablePss -= memInfo.getOtherSwappablePss(i); + otherSharedDirty -= memInfo.getOtherSharedDirty(i); + otherPrivateDirty -= memInfo.getOtherPrivateDirty(i); + otherSharedClean -= memInfo.getOtherSharedClean(i); + otherPrivateClean -= memInfo.getOtherPrivateClean(i); + } pw.println(" "); pw.println(" Objects"); diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index 72ef6065eebf..d8e30e21151b 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -110,38 +110,76 @@ public final class Debug public static class MemoryInfo implements Parcelable { /** The proportional set size for dalvik. */ public int dalvikPss; + /** The proportional set size that is swappable for dalvik. */ + /** @hide We may want to expose this, eventually. */ + public int dalvikSwappablePss; /** The private dirty pages used by dalvik. */ public int dalvikPrivateDirty; /** The shared dirty pages used by dalvik. */ public int dalvikSharedDirty; + /** The private clean pages used by dalvik. */ + /** @hide We may want to expose this, eventually. */ + public int dalvikPrivateClean; /** The shared clean pages used by dalvik. */ + /** @hide We may want to expose this, eventually. */ public int dalvikSharedClean; /** The proportional set size for the native heap. */ public int nativePss; + /** The proportional set size that is swappable for the native heap. */ + /** @hide We may want to expose this, eventually. */ + public int nativeSwappablePss; /** The private dirty pages used by the native heap. */ public int nativePrivateDirty; /** The shared dirty pages used by the native heap. */ public int nativeSharedDirty; + /** The private clean pages used by the native heap. */ + /** @hide We may want to expose this, eventually. */ + public int nativePrivateClean; /** The shared clean pages used by the native heap. */ + /** @hide We may want to expose this, eventually. */ public int nativeSharedClean; /** The proportional set size for everything else. */ public int otherPss; + /** The proportional set size that is swappable for everything else. */ + /** @hide We may want to expose this, eventually. */ + public int otherSwappablePss; /** The private dirty pages used by everything else. */ public int otherPrivateDirty; /** The shared dirty pages used by everything else. */ public int otherSharedDirty; + /** The private clean pages used by everything else. */ + /** @hide We may want to expose this, eventually. */ + public int otherPrivateClean; /** The shared clean pages used by everything else. */ + /** @hide We may want to expose this, eventually. */ public int otherSharedClean; /** @hide */ public static final int NUM_OTHER_STATS = 12; /** @hide */ - public static final int NUM_CATEGORIES = 4; + public static final int NUM_DVK_STATS = 5; - private int[] otherStats = new int[NUM_OTHER_STATS*NUM_CATEGORIES]; + /** @hide */ + public static final int NUM_CATEGORIES = 6; + + /** @hide */ + public static final int offsetPss = 0; + /** @hide */ + public static final int offsetSwappablePss = 1; + /** @hide */ + public static final int offsetPrivateDirty = 2; + /** @hide */ + public static final int offsetSharedDirty = 3; + /** @hide */ + public static final int offsetPrivateClean = 4; + /** @hide */ + public static final int offsetSharedClean = 5; + + + private int[] otherStats = new int[(NUM_OTHER_STATS+NUM_DVK_STATS)*NUM_CATEGORIES]; public MemoryInfo() { } @@ -153,6 +191,14 @@ public final class Debug return dalvikPss + nativePss + otherPss; } + + /** + * Return total PSS memory usage in kB. + */ + public int getTotalSwappablePss() { + return dalvikSwappablePss + nativeSwappablePss + otherSwappablePss; + } + /** * Return total private dirty memory usage in kB. */ @@ -170,30 +216,50 @@ public final class Debug /** * Return total shared clean memory usage in kB. */ + public int getTotalPrivateClean() { + return dalvikPrivateClean + nativePrivateClean + otherPrivateClean; + } + + /** + * Return total shared clean memory usage in kB. + */ public int getTotalSharedClean() { return dalvikSharedClean + nativeSharedClean + otherSharedClean; } /* @hide */ public int getOtherPss(int which) { - return otherStats[which*NUM_CATEGORIES]; + return otherStats[which*NUM_CATEGORIES + offsetPss]; } + + /* @hide */ + public int getOtherSwappablePss(int which) { + return otherStats[which*NUM_CATEGORIES + offsetSwappablePss]; + } + + /* @hide */ public int getOtherPrivateDirty(int which) { - return otherStats[which*NUM_CATEGORIES + 1]; + return otherStats[which*NUM_CATEGORIES + offsetPrivateDirty]; } /* @hide */ public int getOtherSharedDirty(int which) { - return otherStats[which*NUM_CATEGORIES + 2]; + return otherStats[which*NUM_CATEGORIES + offsetSharedDirty]; } /* @hide */ + public int getOtherPrivateClean(int which) { + return otherStats[which*NUM_CATEGORIES + offsetPrivateClean]; + } + + + /* @hide */ public int getOtherSharedClean(int which) { - return otherStats[which*NUM_CATEGORIES + 3]; + return otherStats[which*NUM_CATEGORIES + offsetSharedClean]; } - + /* @hide */ public static String getOtherLabel(int which) { switch (which) { @@ -209,6 +275,11 @@ public final class Debug case 9: return "code mmap"; case 10: return "image mmap"; case 11: return "Other mmap"; + case 12: return ".Heap"; + case 13: return ".LOS"; + case 14: return ".LinearAlloc"; + case 15: return ".GC"; + case 16: return ".JITCache"; default: return "????"; } } @@ -219,32 +290,44 @@ public final class Debug public void writeToParcel(Parcel dest, int flags) { dest.writeInt(dalvikPss); + dest.writeInt(dalvikSwappablePss); dest.writeInt(dalvikPrivateDirty); dest.writeInt(dalvikSharedDirty); + dest.writeInt(dalvikPrivateClean); dest.writeInt(dalvikSharedClean); dest.writeInt(nativePss); + dest.writeInt(nativeSwappablePss); dest.writeInt(nativePrivateDirty); dest.writeInt(nativeSharedDirty); + dest.writeInt(nativePrivateClean); dest.writeInt(nativeSharedClean); dest.writeInt(otherPss); + dest.writeInt(otherSwappablePss); dest.writeInt(otherPrivateDirty); dest.writeInt(otherSharedDirty); + dest.writeInt(otherPrivateClean); dest.writeInt(otherSharedClean); dest.writeIntArray(otherStats); } public void readFromParcel(Parcel source) { dalvikPss = source.readInt(); + dalvikSwappablePss = source.readInt(); dalvikPrivateDirty = source.readInt(); dalvikSharedDirty = source.readInt(); + dalvikPrivateClean = source.readInt(); dalvikSharedClean = source.readInt(); nativePss = source.readInt(); + nativeSwappablePss = source.readInt(); nativePrivateDirty = source.readInt(); nativeSharedDirty = source.readInt(); + nativePrivateClean = source.readInt(); nativeSharedClean = source.readInt(); otherPss = source.readInt(); + otherSwappablePss = source.readInt(); otherPrivateDirty = source.readInt(); otherSharedDirty = source.readInt(); + otherPrivateClean = source.readInt(); otherSharedClean = source.readInt(); otherStats = source.createIntArray(); } diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp index ba8266621100..e356c28da1a2 100644 --- a/core/jni/android_os_Debug.cpp +++ b/core/jni/android_os_Debug.cpp @@ -55,39 +55,51 @@ enum { HEAP_OAT, HEAP_ART, HEAP_UNKNOWN_MAP, + HEAP_DALVIK_NORMAL, + HEAP_DALVIK_LARGE, + HEAP_DALVIK_LINEARALLOC, + HEAP_DALVIK_ACCOUNTING, + HEAP_DALVIK_CODE_CACHE, _NUM_HEAP, + _NUM_EXCLUSIVE_HEAP = HEAP_UNKNOWN_MAP+1, _NUM_CORE_HEAP = HEAP_NATIVE+1 }; struct stat_fields { jfieldID pss_field; + jfieldID pssSwappable_field; jfieldID privateDirty_field; jfieldID sharedDirty_field; + jfieldID privateClean_field; jfieldID sharedClean_field; }; struct stat_field_names { const char* pss_name; + const char* pssSwappable_name; const char* privateDirty_name; const char* sharedDirty_name; + const char* privateClean_name; const char* sharedClean_name; }; static stat_fields stat_fields[_NUM_CORE_HEAP]; static stat_field_names stat_field_names[_NUM_CORE_HEAP] = { - { "otherPss", "otherPrivateDirty", "otherSharedDirty", "otherSharedClean" }, - { "dalvikPss", "dalvikPrivateDirty", "dalvikSharedDirty", "dalvikSharedClean" }, - { "nativePss", "nativePrivateDirty", "nativeSharedDirty", "nativeSharedClean" } + { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty", "otherPrivateClean", "otherSharedClean" }, + { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty", "dalvikPrivateClean", "dalvikSharedClean" }, + { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty", "nativePrivateClean", "nativeSharedClean" } }; jfieldID otherStats_field; struct stats_t { int pss; + int swappablePss; int privateDirty; int sharedDirty; + int privateClean; int sharedClean; }; @@ -129,9 +141,11 @@ static void read_mapinfo(FILE *fp, stats_t* stats) int len, nameLen; bool skip, done = false; - unsigned size = 0, resident = 0, pss = 0; + unsigned size = 0, resident = 0, pss = 0, swappable_pss = 0; + float sharing_proportion = 0.0; unsigned shared_clean = 0, shared_dirty = 0; unsigned private_clean = 0, private_dirty = 0; + bool is_swappable = false; unsigned referenced = 0; unsigned temp; @@ -142,6 +156,7 @@ static void read_mapinfo(FILE *fp, stats_t* stats) int name_pos; int whichHeap = HEAP_UNKNOWN; + int subHeap = HEAP_UNKNOWN; int prevHeap = HEAP_UNKNOWN; if(fgets(line, sizeof(line), fp) == 0) return; @@ -150,7 +165,9 @@ static void read_mapinfo(FILE *fp, stats_t* stats) prevHeap = whichHeap; prevEnd = end; whichHeap = HEAP_UNKNOWN; + subHeap = HEAP_UNKNOWN; skip = false; + is_swappable = false; len = strlen(line); if (len < 1) return; @@ -170,6 +187,26 @@ static void read_mapinfo(FILE *fp, stats_t* stats) whichHeap = HEAP_NATIVE; } else if (strstr(name, "/dev/ashmem/dalvik-") == name) { whichHeap = HEAP_DALVIK; + if (strstr(name, "/dev/ashmem/dalvik-LinearAlloc") == name) { + subHeap = HEAP_DALVIK_LINEARALLOC; + } else if ((strstr(name, "/dev/ashmem/dalvik-mark") == name) || + (strstr(name, "/dev/ashmem/dalvik-allocspace alloc space live-bitmap") == name) || + (strstr(name, "/dev/ashmem/dalvik-allocspace alloc space mark-bitmap") == name) || + (strstr(name, "/dev/ashmem/dalvik-card table") == name) || + (strstr(name, "/dev/ashmem/dalvik-allocation stack") == name) || + (strstr(name, "/dev/ashmem/dalvik-live stack") == name) || + (strstr(name, "/dev/ashmem/dalvik-imagespace") == name) || + (strstr(name, "/dev/ashmem/dalvik-bitmap") == name) || + (strstr(name, "/dev/ashmem/dalvik-card-table") == name) || + (strstr(name, "/dev/ashmem/dalvik-mark-stack") == name) || + (strstr(name, "/dev/ashmem/dalvik-aux-structure") == name)) { + subHeap = HEAP_DALVIK_ACCOUNTING; + } else if (strstr(name, "/dev/ashmem/dalvik-large") == name) { + subHeap = HEAP_DALVIK_LARGE; + } else if (strstr(name, "/dev/ashmem/dalvik-jit-code-cache") == name) { + subHeap = HEAP_DALVIK_CODE_CACHE; + } else + subHeap = HEAP_DALVIK_NORMAL; } else if (strstr(name, "[stack") == name) { whichHeap = HEAP_STACK; } else if (strstr(name, "/dev/ashmem/CursorWindow") == name) { @@ -180,19 +217,26 @@ static void read_mapinfo(FILE *fp, stats_t* stats) whichHeap = HEAP_UNKNOWN_DEV; } else if (nameLen > 3 && strcmp(name+nameLen-3, ".so") == 0) { whichHeap = HEAP_SO; + is_swappable = true; } else if (nameLen > 4 && strcmp(name+nameLen-4, ".jar") == 0) { whichHeap = HEAP_JAR; + is_swappable = true; } else if (nameLen > 4 && strcmp(name+nameLen-4, ".apk") == 0) { whichHeap = HEAP_APK; + is_swappable = true; } else if (nameLen > 4 && strcmp(name+nameLen-4, ".ttf") == 0) { whichHeap = HEAP_TTF; + is_swappable = true; } else if ((nameLen > 4 && strcmp(name+nameLen-4, ".dex") == 0) || (nameLen > 5 && strcmp(name+nameLen-5, ".odex") == 0)) { whichHeap = HEAP_DEX; + is_swappable = true; } else if (nameLen > 4 && strcmp(name+nameLen-4, ".oat") == 0) { whichHeap = HEAP_OAT; + is_swappable = true; } else if (nameLen > 4 && strcmp(name+nameLen-4, ".art") == 0) { whichHeap = HEAP_ART; + is_swappable = true; } else if (nameLen > 0) { whichHeap = HEAP_UNKNOWN_MAP; } else if (start == prevEnd && prevHeap == HEAP_SO) { @@ -234,10 +278,29 @@ static void read_mapinfo(FILE *fp, stats_t* stats) } if (!skip) { + 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); + } + swappable_pss = (sharing_proportion*shared_clean) + private_clean; + } else + swappable_pss = 0; + stats[whichHeap].pss += pss; + stats[whichHeap].swappablePss += swappable_pss; stats[whichHeap].privateDirty += private_dirty; stats[whichHeap].sharedDirty += shared_dirty; + stats[whichHeap].privateClean += private_clean; stats[whichHeap].sharedClean += shared_clean; + if (whichHeap == HEAP_DALVIK) { + stats[subHeap].pss += pss; + stats[subHeap].swappablePss += swappable_pss; + stats[subHeap].privateDirty += private_dirty; + stats[subHeap].sharedDirty += shared_dirty; + stats[subHeap].privateClean += private_clean; + stats[subHeap].sharedClean += shared_clean; + } } } } @@ -261,22 +324,28 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, stats_t stats[_NUM_HEAP]; memset(&stats, 0, sizeof(stats)); + load_maps(pid, stats); - for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) { + for (int i=_NUM_CORE_HEAP; i<_NUM_EXCLUSIVE_HEAP; i++) { stats[HEAP_UNKNOWN].pss += stats[i].pss; + stats[HEAP_UNKNOWN].swappablePss += stats[i].swappablePss; stats[HEAP_UNKNOWN].privateDirty += stats[i].privateDirty; stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty; + stats[HEAP_UNKNOWN].privateClean += stats[i].privateClean; stats[HEAP_UNKNOWN].sharedClean += stats[i].sharedClean; } for (int i=0; i<_NUM_CORE_HEAP; i++) { env->SetIntField(object, stat_fields[i].pss_field, stats[i].pss); + env->SetIntField(object, stat_fields[i].pssSwappable_field, stats[i].swappablePss); env->SetIntField(object, stat_fields[i].privateDirty_field, stats[i].privateDirty); 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); } + jintArray otherIntArray = (jintArray)env->GetObjectField(object, otherStats_field); jint* otherArray = (jint*)env->GetPrimitiveArrayCritical(otherIntArray, 0); @@ -287,8 +356,10 @@ static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, int j=0; for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) { otherArray[j++] = stats[i].pss; + otherArray[j++] = stats[i].swappablePss; otherArray[j++] = stats[i].privateDirty; otherArray[j++] = stats[i].sharedDirty; + otherArray[j++] = stats[i].privateClean; otherArray[j++] = stats[i].sharedClean; } @@ -630,11 +701,13 @@ int register_android_os_Debug(JNIEnv *env) // Sanity check the number of other statistics expected in Java matches here. jfieldID numOtherStats_field = env->GetStaticFieldID(clazz, "NUM_OTHER_STATS", "I"); jint numOtherStats = env->GetStaticIntField(clazz, numOtherStats_field); + jfieldID numDvkStats_field = env->GetStaticFieldID(clazz, "NUM_DVK_STATS", "I"); + jint numDvkStats = env->GetStaticIntField(clazz, numDvkStats_field); int expectedNumOtherStats = _NUM_HEAP - _NUM_CORE_HEAP; - if (numOtherStats != expectedNumOtherStats) { + if ((numOtherStats + numDvkStats) != expectedNumOtherStats) { jniThrowExceptionFmt(env, "java/lang/RuntimeException", - "android.os.Debug.Meminfo.NUM_OTHER_STATS=%d expected %d", - numOtherStats, expectedNumOtherStats); + "android.os.Debug.Meminfo.NUM_OTHER_STATS+android.os.Debug.Meminfo.NUM_DVK_STATS=%d expected %d", + numOtherStats+numDvkStats, expectedNumOtherStats); return JNI_ERR; } @@ -643,10 +716,14 @@ int register_android_os_Debug(JNIEnv *env) for (int i=0; i<_NUM_CORE_HEAP; i++) { stat_fields[i].pss_field = env->GetFieldID(clazz, stat_field_names[i].pss_name, "I"); + stat_fields[i].pssSwappable_field = + env->GetFieldID(clazz, stat_field_names[i].pssSwappable_name, "I"); stat_fields[i].privateDirty_field = env->GetFieldID(clazz, stat_field_names[i].privateDirty_name, "I"); stat_fields[i].sharedDirty_field = env->GetFieldID(clazz, stat_field_names[i].sharedDirty_name, "I"); + stat_fields[i].privateClean_field = + 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"); } |