Merge "Add more memory usage stats"
diff --git a/api/current.txt b/api/current.txt
index 3685cf4..96a8481 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -17065,28 +17065,29 @@
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 82ecfa3..d1bf0af 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -543,13 +543,13 @@
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 @@
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 @@
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 @@
+ 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 @@
}
// 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 72ef606..d8e30e2 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -110,38 +110,76 @@
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 @@
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 @@
/**
* 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 getOtherSharedClean(int which) {
- return otherStats[which*NUM_CATEGORIES + 3];
+ public int getOtherPrivateClean(int which) {
+ return otherStats[which*NUM_CATEGORIES + offsetPrivateClean];
}
-
+
+
+ /* @hide */
+ public int getOtherSharedClean(int which) {
+ return otherStats[which*NUM_CATEGORIES + offsetSharedClean];
+ }
+
/* @hide */
public static String getOtherLabel(int which) {
switch (which) {
@@ -209,6 +275,11 @@
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 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 ba82666..e356c28 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -55,39 +55,51 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
// 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 @@
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");
}