Add 'App Summary' section to meminfo.
The 'App Summary' section is shown by default when other memory
details are shown. This adds a new meminfo flag '-s' to show only the
App Summary section.
Change-Id: I66913673cd3afca873a8b13e45abe071d4c57b82
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index f16406a..f506d59 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -571,8 +571,6 @@
private native void dumpGraphicsInfo(FileDescriptor fd);
private class ApplicationThread extends ApplicationThreadNative {
- 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";
private int mLastProcessState = -1;
@@ -972,18 +970,18 @@
@Override
public void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin,
- boolean dumpFullInfo, boolean dumpDalvik, String[] args) {
+ boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly, String[] args) {
FileOutputStream fout = new FileOutputStream(fd);
PrintWriter pw = new FastPrintWriter(fout);
try {
- dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik);
+ dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly);
} finally {
pw.flush();
}
}
private void dumpMemInfo(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
- boolean dumpFullInfo, boolean dumpDalvik) {
+ boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly) {
long nativeMax = Debug.getNativeHeapSize() / 1024;
long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
@@ -1007,7 +1005,8 @@
long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class);
SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
- dumpMemInfoTable(pw, memInfo, checkin, dumpFullInfo, dumpDalvik, Process.myPid(),
+ dumpMemInfoTable(pw, memInfo, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly,
+ Process.myPid(),
(mBoundApplication != null) ? mBoundApplication.processName : "unknown",
nativeMax, nativeAllocated, nativeFree,
dalvikMax, dalvikAllocated, dalvikFree);
@@ -1935,6 +1934,9 @@
= "%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 ONE_COUNT_COLUMN_HEADER = "%21s %8s";
// Formatting for checkin service - update version if row format changes
private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 3;
@@ -1944,7 +1946,8 @@
}
public static void dumpMemInfoTable(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin,
- boolean dumpFullInfo, boolean dumpDalvik, int pid, String processName,
+ boolean dumpFullInfo, boolean dumpDalvik, boolean dumpSummaryOnly,
+ int pid, String processName,
long nativeMax, long nativeAllocated, long nativeFree,
long dalvikMax, long dalvikAllocated, long dalvikFree) {
@@ -2025,106 +2028,50 @@
return;
}
- // otherwise, show human-readable format
- if (dumpFullInfo) {
- printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private",
- "Shared", "Private", "Swapped", "Heap", "Heap", "Heap");
- printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty",
- "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, memInfo.nativeSwappedOut,
- nativeMax, nativeAllocated, nativeFree);
- printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
- memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
- memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
- memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
- dalvikMax, dalvikAllocated, dalvikFree);
- } else {
- 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.nativePrivateDirty,
- memInfo.nativePrivateClean, memInfo.nativeSwappedOut,
- nativeMax, nativeAllocated, nativeFree);
- printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
- memInfo.dalvikPrivateDirty,
- memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
- 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;
- int otherSwappedOut = memInfo.otherSwappedOut;
-
- for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
- final int myPss = memInfo.getOtherPss(i);
- final int mySwappablePss = memInfo.getOtherSwappablePss(i);
- final int mySharedDirty = memInfo.getOtherSharedDirty(i);
- 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 || mySwappedOut != 0) {
- if (dumpFullInfo) {
- printRow(pw, HEAP_FULL_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
- myPss, mySwappablePss, mySharedDirty, myPrivateDirty,
- mySharedClean, myPrivateClean, mySwappedOut, "", "", "");
- } else {
- printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
- myPss, myPrivateDirty,
- myPrivateClean, mySwappedOut, "", "", "");
- }
- otherPss -= myPss;
- otherSwappablePss -= mySwappablePss;
- otherSharedDirty -= mySharedDirty;
- otherPrivateDirty -= myPrivateDirty;
- otherSharedClean -= mySharedClean;
- otherPrivateClean -= myPrivateClean;
- otherSwappedOut -= mySwappedOut;
+ if (!dumpSummaryOnly) {
+ if (dumpFullInfo) {
+ printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private",
+ "Shared", "Private", "Swapped", "Heap", "Heap", "Heap");
+ printRow(pw, HEAP_FULL_COLUMN, "", "Total", "Clean", "Dirty", "Dirty",
+ "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, memInfo.nativeSwappedOut,
+ nativeMax, nativeAllocated, nativeFree);
+ printRow(pw, HEAP_FULL_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
+ memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty,
+ memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean,
+ memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
+ dalvikMax, dalvikAllocated, dalvikFree);
+ } else {
+ 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.nativePrivateDirty,
+ memInfo.nativePrivateClean, memInfo.nativeSwappedOut,
+ nativeMax, nativeAllocated, nativeFree);
+ printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss,
+ memInfo.dalvikPrivateDirty,
+ memInfo.dalvikPrivateClean, memInfo.dalvikSwappedOut,
+ dalvikMax, dalvikAllocated, dalvikFree);
}
- }
- 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(),
- memInfo.getTotalSwappedOut(), nativeMax+dalvikMax,
- nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
- } else {
- printRow(pw, HEAP_COLUMN, "Unknown", otherPss,
- otherPrivateDirty, otherPrivateClean, otherSwappedOut,
- "", "", "");
- printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
- memInfo.getTotalPrivateDirty(),
- memInfo.getTotalPrivateClean(),
- memInfo.getTotalSwappedOut(),
- nativeMax+dalvikMax,
- nativeAllocated+dalvikAllocated, nativeFree+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;
+ int otherSwappedOut = memInfo.otherSwappedOut;
- if (dumpDalvik) {
- pw.println(" ");
- pw.println(" Dalvik Details");
-
- for (int i=Debug.MemoryInfo.NUM_OTHER_STATS;
- i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) {
+ for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
final int myPss = memInfo.getOtherPss(i);
final int mySwappablePss = memInfo.getOtherSwappablePss(i);
final int mySharedDirty = memInfo.getOtherSharedDirty(i);
@@ -2133,7 +2080,7 @@
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,
@@ -2143,9 +2090,89 @@
myPss, myPrivateDirty,
myPrivateClean, mySwappedOut, "", "", "");
}
+ otherPss -= myPss;
+ otherSwappablePss -= mySwappablePss;
+ otherSharedDirty -= mySharedDirty;
+ 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(),
+ memInfo.getTotalSwappedOut(), nativeMax+dalvikMax,
+ nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
+ } else {
+ printRow(pw, HEAP_COLUMN, "Unknown", otherPss,
+ otherPrivateDirty, otherPrivateClean, otherSwappedOut,
+ "", "", "");
+ printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
+ memInfo.getTotalPrivateDirty(),
+ memInfo.getTotalPrivateClean(),
+ memInfo.getTotalSwappedOut(),
+ nativeMax+dalvikMax,
+ nativeAllocated+dalvikAllocated, nativeFree+dalvikFree);
+ }
+
+ if (dumpDalvik) {
+ pw.println(" ");
+ pw.println(" Dalvik Details");
+
+ for (int i=Debug.MemoryInfo.NUM_OTHER_STATS;
+ i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) {
+ final int myPss = memInfo.getOtherPss(i);
+ final int mySwappablePss = memInfo.getOtherSwappablePss(i);
+ final int mySharedDirty = memInfo.getOtherSharedDirty(i);
+ 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, mySwappedOut, "", "", "");
+ } else {
+ printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
+ myPss, myPrivateDirty,
+ myPrivateClean, mySwappedOut, "", "", "");
+ }
+ }
}
}
}
+
+ pw.println(" ");
+ pw.println(" App Summary");
+ printRow(pw, ONE_COUNT_COLUMN_HEADER, "", "Pss(KB)");
+ printRow(pw, ONE_COUNT_COLUMN_HEADER, "", "------");
+ printRow(pw, ONE_COUNT_COLUMN,
+ "Java Heap:", memInfo.getSummaryJavaHeap());
+ printRow(pw, ONE_COUNT_COLUMN,
+ "Native Heap:", memInfo.getSummaryNativeHeap());
+ printRow(pw, ONE_COUNT_COLUMN,
+ "Code:", memInfo.getSummaryCode());
+ printRow(pw, ONE_COUNT_COLUMN,
+ "Stack:", memInfo.getSummaryStack());
+ printRow(pw, ONE_COUNT_COLUMN,
+ "Graphics:", memInfo.getSummaryGraphics());
+ printRow(pw, ONE_COUNT_COLUMN,
+ "Private Other:", memInfo.getSummaryPrivateOther());
+ printRow(pw, ONE_COUNT_COLUMN,
+ "System:", memInfo.getSummarySystem());
+ pw.println(" ");
+ printRow(pw, TWO_COUNT_COLUMNS,
+ "TOTAL:", memInfo.getSummaryTotalPss(),
+ "TOTAL SWAP (KB):", memInfo.getSummaryTotalSwap());
}
public void registerOnActivityPausedListener(Activity activity,
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index b6989ab..1461380 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -529,10 +529,12 @@
boolean checkin = data.readInt() != 0;
boolean dumpInfo = data.readInt() != 0;
boolean dumpDalvik = data.readInt() != 0;
+ boolean dumpSummaryOnly = data.readInt() != 0;
String[] args = data.readStringArray();
if (fd != null) {
try {
- dumpMemInfo(fd.getFileDescriptor(), mi, checkin, dumpInfo, dumpDalvik, args);
+ dumpMemInfo(fd.getFileDescriptor(), mi, checkin, dumpInfo,
+ dumpDalvik, dumpSummaryOnly, args);
} finally {
try {
fd.close();
@@ -1248,7 +1250,7 @@
}
public void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin,
- boolean dumpInfo, boolean dumpDalvik, String[] args) throws RemoteException {
+ boolean dumpInfo, boolean dumpDalvik, boolean dumpSummaryOnly, String[] args) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
@@ -1257,6 +1259,7 @@
data.writeInt(checkin ? 1 : 0);
data.writeInt(dumpInfo ? 1 : 0);
data.writeInt(dumpDalvik ? 1 : 0);
+ data.writeInt(dumpSummaryOnly ? 1 : 0);
data.writeStringArray(args);
mRemote.transact(DUMP_MEM_INFO_TRANSACTION, data, reply, 0);
reply.readException();
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 3fb82f6..185578f 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -131,7 +131,7 @@
void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) throws RemoteException;
void scheduleTrimMemory(int level) throws RemoteException;
void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin, boolean dumpInfo,
- boolean dumpDalvik, String[] args) throws RemoteException;
+ boolean dumpDalvik, boolean dumpSummaryOnly, String[] args) throws RemoteException;
void dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException;
void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException;
void unstableProviderDied(IBinder provider) throws RemoteException;
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 4aff7a1..19c8fa9d 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -169,6 +169,65 @@
public int otherSwappedOut;
/** @hide */
+ public static final int HEAP_UNKNOWN = 0;
+ /** @hide */
+ public static final int HEAP_DALVIK = 1;
+ /** @hide */
+ public static final int HEAP_NATIVE = 2;
+
+ /** @hide */
+ public static final int OTHER_DALVIK_OTHER = 0;
+ /** @hide */
+ public static final int OTHER_STACK = 1;
+ /** @hide */
+ public static final int OTHER_CURSOR = 2;
+ /** @hide */
+ public static final int OTHER_ASHMEM = 3;
+ /** @hide */
+ public static final int OTHER_GL_DEV = 4;
+ /** @hide */
+ public static final int OTHER_UNKNOWN_DEV = 5;
+ /** @hide */
+ public static final int OTHER_SO = 6;
+ /** @hide */
+ public static final int OTHER_JAR = 7;
+ /** @hide */
+ public static final int OTHER_APK = 8;
+ /** @hide */
+ public static final int OTHER_TTF = 9;
+ /** @hide */
+ public static final int OTHER_DEX = 10;
+ /** @hide */
+ public static final int OTHER_OAT = 11;
+ /** @hide */
+ public static final int OTHER_ART = 12;
+ /** @hide */
+ public static final int OTHER_UNKNOWN_MAP = 13;
+ /** @hide */
+ public static final int OTHER_GRAPHICS = 14;
+ /** @hide */
+ public static final int OTHER_GL = 15;
+ /** @hide */
+ public static final int OTHER_OTHER_MEMTRACK = 16;
+
+ /** @hide */
+ public static final int OTHER_DALVIK_NORMAL = 17;
+ /** @hide */
+ public static final int OTHER_DALVIK_LARGE = 18;
+ /** @hide */
+ public static final int OTHER_DALVIK_LINEARALLOC = 19;
+ /** @hide */
+ public static final int OTHER_DALVIK_ACCOUNTING = 20;
+ /** @hide */
+ public static final int OTHER_DALVIK_CODE_CACHE = 21;
+ /** @hide */
+ public static final int OTHER_DALVIK_ZYGOTE = 22;
+ /** @hide */
+ public static final int OTHER_DALVIK_NON_MOVING = 23;
+ /** @hide */
+ public static final int OTHER_DALVIK_INDIRECT_REFERENCE_TABLE = 24;
+
+ /** @hide */
public static final int NUM_OTHER_STATS = 17;
/** @hide */
@@ -284,6 +343,11 @@
}
/** @hide */
+ public int getOtherPrivate(int which) {
+ return getOtherPrivateClean(which) + getOtherPrivateDirty(which);
+ }
+
+ /** @hide */
public int getOtherSharedClean(int which) {
return otherStats[which*NUM_CATEGORIES + offsetSharedClean];
}
@@ -296,35 +360,157 @@
/** @hide */
public static String getOtherLabel(int which) {
switch (which) {
- case 0: return "Dalvik Other";
- case 1: return "Stack";
- case 2: return "Cursor";
- case 3: return "Ashmem";
- case 4: return "Gfx dev";
- case 5: return "Other dev";
- case 6: return ".so mmap";
- case 7: return ".jar mmap";
- case 8: return ".apk mmap";
- case 9: return ".ttf mmap";
- case 10: return ".dex mmap";
- case 11: return ".oat mmap";
- case 12: return ".art mmap";
- case 13: return "Other mmap";
- case 14: return "EGL mtrack";
- case 15: return "GL mtrack";
- case 16: return "Other mtrack";
- case 17: return ".Heap";
- case 18: return ".LOS";
- case 19: return ".LinearAlloc";
- case 20: return ".GC";
- case 21: return ".JITCache";
- case 22: return ".Zygote";
- case 23: return ".NonMoving";
- case 24: return ".IndirectRef";
+ case OTHER_DALVIK_OTHER: return "Dalvik Other";
+ case OTHER_STACK: return "Stack";
+ case OTHER_CURSOR: return "Cursor";
+ case OTHER_ASHMEM: return "Ashmem";
+ case OTHER_GL_DEV: return "Gfx dev";
+ case OTHER_UNKNOWN_DEV: return "Other dev";
+ case OTHER_SO: return ".so mmap";
+ case OTHER_JAR: return ".jar mmap";
+ case OTHER_APK: return ".apk mmap";
+ case OTHER_TTF: return ".ttf mmap";
+ case OTHER_DEX: return ".dex mmap";
+ case OTHER_OAT: return ".oat mmap";
+ case OTHER_ART: return ".art mmap";
+ case OTHER_UNKNOWN_MAP: return "Other mmap";
+ case OTHER_GRAPHICS: return "EGL mtrack";
+ case OTHER_GL: return "GL mtrack";
+ case OTHER_OTHER_MEMTRACK: return "Other mtrack";
+ case OTHER_DALVIK_NORMAL: return ".Heap";
+ case OTHER_DALVIK_LARGE: return ".LOS";
+ case OTHER_DALVIK_LINEARALLOC: return ".LinearAlloc";
+ case OTHER_DALVIK_ACCOUNTING: return ".GC";
+ case OTHER_DALVIK_CODE_CACHE: return ".JITCache";
+ case OTHER_DALVIK_ZYGOTE: return ".Zygote";
+ case OTHER_DALVIK_NON_MOVING: return ".NonMoving";
+ case OTHER_DALVIK_INDIRECT_REFERENCE_TABLE: return ".IndirectRef";
default: return "????";
}
}
+ /**
+ * Pss of Java Heap bytes in KB due to the application.
+ * Notes:
+ * * OTHER_ART is the boot image. Anything private here is blamed on
+ * the application, not the system.
+ * * dalvikPrivateDirty includes private zygote, which means the
+ * application dirtied something allocated by the zygote. We blame
+ * the application for that memory, not the system.
+ * * Does not include OTHER_DALVIK_OTHER, which is considered VM
+ * Overhead and lumped into Private Other.
+ * * We don't include dalvikPrivateClean, because there should be no
+ * such thing as private clean for the Java Heap.
+ * @hide
+ */
+ public int getSummaryJavaHeap() {
+ return dalvikPrivateDirty + getOtherPrivate(OTHER_ART);
+ }
+
+ /**
+ * Pss of Native Heap bytes in KB due to the application.
+ * Notes:
+ * * Includes private dirty malloc space.
+ * * We don't include nativePrivateClean, because there should be no
+ * such thing as private clean for the Native Heap.
+ * @hide
+ */
+ public int getSummaryNativeHeap() {
+ return nativePrivateDirty;
+ }
+
+ /**
+ * Pss of code and other static resource bytes in KB due to
+ * the application.
+ * @hide
+ */
+ public int getSummaryCode() {
+ return getOtherPrivate(OTHER_SO)
+ + getOtherPrivate(OTHER_JAR)
+ + getOtherPrivate(OTHER_APK)
+ + getOtherPrivate(OTHER_TTF)
+ + getOtherPrivate(OTHER_DEX)
+ + getOtherPrivate(OTHER_OAT);
+ }
+
+ /**
+ * Pss in KB of the stack due to the application.
+ * Notes:
+ * * Includes private dirty stack, which includes both Java and Native
+ * stack.
+ * * Does not include private clean stack, because there should be no
+ * such thing as private clean for the stack.
+ * @hide
+ */
+ public int getSummaryStack() {
+ return getOtherPrivateDirty(OTHER_STACK);
+ }
+
+ /**
+ * Pss in KB of graphics due to the application.
+ * Notes:
+ * * Includes private Gfx, EGL, and GL.
+ * * Warning: These numbers can be misreported by the graphics drivers.
+ * * We don't include shared graphics. It may make sense to, because
+ * shared graphics are likely buffers due to the application
+ * anyway, but it's simpler to implement to just group all shared
+ * memory into the System category.
+ * @hide
+ */
+ public int getSummaryGraphics() {
+ return getOtherPrivate(OTHER_GL_DEV)
+ + getOtherPrivate(OTHER_GRAPHICS)
+ + getOtherPrivate(OTHER_GL);
+ }
+
+ /**
+ * Pss in KB due to the application that haven't otherwise been
+ * accounted for.
+ * @hide
+ */
+ public int getSummaryPrivateOther() {
+ return getTotalPrivateClean()
+ + getTotalPrivateDirty()
+ - getSummaryJavaHeap()
+ - getSummaryNativeHeap()
+ - getSummaryCode()
+ - getSummaryStack()
+ - getSummaryGraphics();
+ }
+
+ /**
+ * Pss in KB due to the system.
+ * Notes:
+ * * Includes all shared memory.
+ * @hide
+ */
+ public int getSummarySystem() {
+ return getTotalPss()
+ - getTotalPrivateClean()
+ - getTotalPrivateDirty();
+ }
+
+ /**
+ * Total Pss in KB.
+ * @hide
+ */
+ public int getSummaryTotalPss() {
+ return getTotalPss();
+ }
+
+ /**
+ * Total Swap in KB.
+ * Notes:
+ * * Some of this memory belongs in other categories, but we don't
+ * know if the Swap memory is shared or private, so we don't know
+ * what to blame on the application and what on the system.
+ * For now, just lump all the Swap in one place.
+ * @hide
+ */
+ public int getSummaryTotalSwap() {
+ return getTotalSwappedOut();
+ }
+
public int describeContents() {
return 0;
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 82dbfeec..d1df7e2 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -14121,6 +14121,7 @@
boolean dumpDetails = false;
boolean dumpFullDetails = false;
boolean dumpDalvik = false;
+ boolean dumpSummaryOnly = false;
boolean oomOnly = false;
boolean isCompact = false;
boolean localOnly = false;
@@ -14141,6 +14142,9 @@
dumpDalvik = true;
} else if ("-c".equals(opt)) {
isCompact = true;
+ } else if ("-s".equals(opt)) {
+ dumpDetails = true;
+ dumpSummaryOnly = true;
} else if ("--oom".equals(opt)) {
oomOnly = true;
} else if ("--local".equals(opt)) {
@@ -14148,10 +14152,11 @@
} else if ("--package".equals(opt)) {
packages = true;
} else if ("-h".equals(opt)) {
- pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
+ pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
pw.println(" -a: include all available information for each process.");
pw.println(" -d: include dalvik details.");
pw.println(" -c: dump in a compact machine-parseable representation.");
+ pw.println(" -s: dump only summary of application memory usage.");
pw.println(" --oom: only show processes organized by oom adj.");
pw.println(" --local: only collect details locally, don't call process.");
pw.println(" --package: interpret process arg as package, dumping all");
@@ -14212,7 +14217,7 @@
mi.dalvikPrivateDirty = (int)tmpLong[0];
}
ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
- dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
+ dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
if (isCheckinRequest) {
pw.println();
}
@@ -14278,7 +14283,7 @@
if (dumpDetails) {
if (localOnly) {
ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
- dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
+ dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
if (isCheckinRequest) {
pw.println();
}
@@ -14286,7 +14291,7 @@
try {
pw.flush();
thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
- dumpDalvik, innerArgs);
+ dumpDalvik, dumpSummaryOnly, innerArgs);
} catch (RemoteException e) {
if (!isCheckinRequest) {
pw.println("Got RemoteException!");