diff options
-rw-r--r-- | core/java/android/app/ActivityThread.java | 107 | ||||
-rw-r--r-- | core/java/android/app/ApplicationThreadNative.java | 12 | ||||
-rw-r--r-- | core/java/android/app/IApplicationThread.java | 4 | ||||
-rw-r--r-- | core/java/android/os/Debug.java | 49 | ||||
-rw-r--r-- | core/jni/android_os_Debug.cpp | 71 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 17 |
6 files changed, 148 insertions, 112 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index d1bf0af..4a41896 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -895,17 +895,18 @@ public final class ActivityThread { @Override public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, - boolean all, String[] args) { + boolean dumpInfo, boolean dumpDalvik, String[] args) { FileOutputStream fout = new FileOutputStream(fd); PrintWriter pw = new PrintWriter(fout); try { - return dumpMemInfo(pw, checkin, all); + return dumpMemInfo(pw, checkin, dumpInfo, dumpDalvik); } finally { pw.flush(); } } - private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean all) { + private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean dumpInfo, + boolean dumpDalvik) { long nativeMax = Debug.getNativeHeapSize() / 1024; long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; long nativeFree = Debug.getNativeHeapFreeSize() / 1024; @@ -913,7 +914,7 @@ public final class ActivityThread { Debug.MemoryInfo memInfo = new Debug.MemoryInfo(); Debug.getMemoryInfo(memInfo); - if (!all) { + if (!dumpInfo) { return memInfo; } @@ -1040,16 +1041,20 @@ public final class ActivityThread { } // otherwise, show human-readable format - 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.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); + printRow(pw, HEAP_COLUMN, "", "Pss", "Pss","Shared", "Private", "Shared", "Private", + "Heap", "Heap", "Heap"); + printRow(pw, HEAP_COLUMN, "", "Total", "Clean", "Dirty", "Dirty", "Clean", "Clean", + "Size", "Alloc", "Free"); + printRow(pw, HEAP_COLUMN, "", "------", "------", "------", "------", "------", + "------", "------", "------", "------"); + printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss, memInfo.nativeSwappablePss, + memInfo.nativeSharedDirty, + memInfo.nativePrivateDirty, memInfo.nativeSharedClean, + memInfo.nativePrivateClean, nativeMax, nativeAllocated, nativeFree); + printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss, memInfo.dalvikSwappablePss, + memInfo.dalvikSharedDirty, + memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean, + memInfo.dalvikPrivateClean, dalvikMax, dalvikAllocated, dalvikFree); int otherPss = memInfo.otherPss; int otherSwappablePss = memInfo.otherSwappablePss; @@ -1059,42 +1064,56 @@ public final class ActivityThread { 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.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); + 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); + if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 + || mySharedClean != 0 || myPrivateClean != 0) { + printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), + myPss, mySwappablePss, mySharedDirty, myPrivateDirty, + mySharedClean, myPrivateClean, "", "", ""); + otherPss -= myPss; + otherSwappablePss -= mySwappablePss; + otherSharedDirty -= mySharedDirty; + otherPrivateDirty -= myPrivateDirty; + otherSharedClean -= mySharedClean; + otherPrivateClean -= myPrivateClean; + } } 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); + printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(), + memInfo.getTotalSwappablePss(), + memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(), + memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(), + 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); + if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 + || mySharedClean != 0 || myPrivateClean != 0) { + printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), + myPss, mySwappablePss, mySharedDirty, myPrivateDirty, + mySharedClean, myPrivateClean, "", "", ""); + } + } } pw.println(" "); diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index b1c58f2..e903447 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -524,12 +524,13 @@ public abstract class ApplicationThreadNative extends Binder data.enforceInterface(IApplicationThread.descriptor); ParcelFileDescriptor fd = data.readFileDescriptor(); boolean checkin = data.readInt() != 0; - boolean all = data.readInt() != 0; + boolean dumpInfo = data.readInt() != 0; + boolean dumpDalvik = data.readInt() != 0; String[] args = data.readStringArray(); Debug.MemoryInfo mi = null; if (fd != null) { try { - mi = dumpMemInfo(fd.getFileDescriptor(), checkin, all, args); + mi = dumpMemInfo(fd.getFileDescriptor(), checkin, dumpInfo, dumpDalvik, args); } finally { try { fd.close(); @@ -1159,14 +1160,15 @@ class ApplicationThreadProxy implements IApplicationThread { IBinder.FLAG_ONEWAY); } - public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean all, - String[] args) throws RemoteException { + public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean dumpInfo, + boolean dumpDalvik, String[] args) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeFileDescriptor(fd); data.writeInt(checkin ? 1 : 0); - data.writeInt(all ? 1 : 0); + data.writeInt(dumpInfo ? 1 : 0); + data.writeInt(dumpDalvik ? 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 3189b31..a009bd3 100644 --- a/core/java/android/app/IApplicationThread.java +++ b/core/java/android/app/IApplicationThread.java @@ -126,8 +126,8 @@ public interface IApplicationThread extends IInterface { void setCoreSettings(Bundle coreSettings) throws RemoteException; void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) throws RemoteException; void scheduleTrimMemory(int level) throws RemoteException; - Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean all, - String[] args) throws RemoteException; + Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean dumpInfo, + boolean dumpDalvik, 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 d8e30e2..362ae29 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -108,19 +108,19 @@ public final class Debug * process. The returns info broken down by dalvik, native, and other. All results are in kB. */ public static class MemoryInfo implements Parcelable { - /** The proportional set size for dalvik. */ + /** The proportional set size for dalvik heap. (Doesn't include other Dalvik overhead.) */ public int dalvikPss; - /** The proportional set size that is swappable for dalvik. */ + /** The proportional set size that is swappable for dalvik heap. */ /** @hide We may want to expose this, eventually. */ public int dalvikSwappablePss; - /** The private dirty pages used by dalvik. */ + /** The private dirty pages used by dalvik heap. */ public int dalvikPrivateDirty; - /** The shared dirty pages used by dalvik. */ + /** The shared dirty pages used by dalvik heap. */ public int dalvikSharedDirty; - /** The private clean pages used by dalvik. */ + /** The private clean pages used by dalvik heap. */ /** @hide We may want to expose this, eventually. */ public int dalvikPrivateClean; - /** The shared clean pages used by dalvik. */ + /** The shared clean pages used by dalvik heap. */ /** @hide We may want to expose this, eventually. */ public int dalvikSharedClean; @@ -157,7 +157,7 @@ public final class Debug public int otherSharedClean; /** @hide */ - public static final int NUM_OTHER_STATS = 12; + public static final int NUM_OTHER_STATS = 13; /** @hide */ public static final int NUM_DVK_STATS = 5; @@ -263,23 +263,24 @@ public final class Debug /* @hide */ public static String getOtherLabel(int which) { switch (which) { - case 0: return "Stack"; - case 1: return "Cursor"; - case 2: return "Ashmem"; - case 3: return "Other dev"; - case 4: return ".so mmap"; - case 5: return ".jar mmap"; - case 6: return ".apk mmap"; - case 7: return ".ttf mmap"; - case 8: return ".dex mmap"; - 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"; + case 0: return "Dalvik Other"; + case 1: return "Stack"; + case 2: return "Cursor"; + case 3: return "Ashmem"; + case 4: return "Other dev"; + case 5: return ".so mmap"; + case 6: return ".jar mmap"; + case 7: return ".apk mmap"; + case 8: return ".ttf mmap"; + case 9: return ".dex mmap"; + case 10: return "code mmap"; + case 11: return "image mmap"; + case 12: return "Other mmap"; + case 13: return ".Heap"; + case 14: return ".LOS"; + case 15: return ".LinearAlloc"; + case 16: return ".GC"; + case 17: return ".JITCache"; default: return "????"; } } diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp index e356c28..f4cf2ee 100644 --- a/core/jni/android_os_Debug.cpp +++ b/core/jni/android_os_Debug.cpp @@ -43,6 +43,7 @@ enum { HEAP_UNKNOWN, HEAP_DALVIK, HEAP_NATIVE, + HEAP_DALVIK_OTHER, HEAP_STACK, HEAP_CURSOR, HEAP_ASHMEM, @@ -55,6 +56,7 @@ enum { HEAP_OAT, HEAP_ART, HEAP_UNKNOWN_MAP, + HEAP_DALVIK_NORMAL, HEAP_DALVIK_LARGE, HEAP_DALVIK_LINEARALLOC, @@ -182,38 +184,45 @@ static void read_mapinfo(FILE *fp, stats_t* stats) name = line + name_pos; nameLen = strlen(name); - if ((strstr(name, "[heap]") == name) || - (strstr(name, "/dev/ashmem/libc malloc") == name)) { + if ((strstr(name, "[heap]") == name)) { 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) { + } else if (strncmp(name, "/dev/ashmem", 11) == 0) { + if (strncmp(name, "/dev/ashmem/dalvik-", 19) == 0) { + whichHeap = HEAP_DALVIK_OTHER; + 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) { + whichHeap = HEAP_DALVIK; + subHeap = HEAP_DALVIK_LARGE; + } else if (strstr(name, "/dev/ashmem/dalvik-jit-code-cache") == name) { + subHeap = HEAP_DALVIK_CODE_CACHE; + } else { + // This is the regular Dalvik heap. + whichHeap = HEAP_DALVIK; + subHeap = HEAP_DALVIK_NORMAL; + } + } else if (strncmp(name, "/dev/ashmem/CursorWindow", 24) == 0) { + whichHeap = HEAP_CURSOR; + } else if (strncmp(name, "/dev/ashmem/libc malloc", 23) == 0) { + whichHeap = HEAP_NATIVE; + } else { + whichHeap = HEAP_ASHMEM; + } + } else if (strncmp(name, "[stack", 6) == 0) { whichHeap = HEAP_STACK; - } else if (strstr(name, "/dev/ashmem/CursorWindow") == name) { - whichHeap = HEAP_CURSOR; - } else if (strstr(name, "/dev/ashmem/") == name) { - whichHeap = HEAP_ASHMEM; - } else if (strstr(name, "/dev/") == name) { + } else if (strncmp(name, "/dev/", 5) == 0) { whichHeap = HEAP_UNKNOWN_DEV; } else if (nameLen > 3 && strcmp(name+nameLen-3, ".so") == 0) { whichHeap = HEAP_SO; @@ -293,7 +302,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; - if (whichHeap == HEAP_DALVIK) { + if (whichHeap == HEAP_DALVIK || whichHeap == HEAP_DALVIK_OTHER) { stats[subHeap].pss += pss; stats[subHeap].swappablePss += swappable_pss; stats[subHeap].privateDirty += private_dirty; diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index dcb2984..264cd7d 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -10626,7 +10626,8 @@ public final class ActivityManagerService extends ActivityManagerNative final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) { - boolean dumpAll = false; + boolean dumpDetails = false; + boolean dumpDalvik = false; boolean oomOnly = false; int opti = 0; @@ -10637,12 +10638,16 @@ public final class ActivityManagerService extends ActivityManagerNative } opti++; if ("-a".equals(opt)) { - dumpAll = true; + dumpDetails = true; + dumpDalvik = true; + } else if ("-d".equals(opt)) { + dumpDalvik = true; } else if ("--oom".equals(opt)) { oomOnly = true; } else if ("-h".equals(opt)) { pw.println("meminfo dump options: [-a] [--oom] [process]"); pw.println(" -a: include all available information for each process."); + pw.println(" -d: include dalvik details when dumping process details."); pw.println(" --oom: only show processes organized by oom adj."); pw.println("If [process] is specified it can be the name or "); pw.println("pid of a specific process to dump."); @@ -10662,7 +10667,7 @@ public final class ActivityManagerService extends ActivityManagerNative long realtime = SystemClock.elapsedRealtime(); if (procs.size() == 1 || isCheckinRequest) { - dumpAll = true; + dumpDetails = true; } if (isCheckinRequest) { @@ -10690,14 +10695,14 @@ public final class ActivityManagerService extends ActivityManagerNative for (int i = procs.size() - 1 ; i >= 0 ; i--) { ProcessRecord r = procs.get(i); if (r.thread != null) { - if (!isCheckinRequest && dumpAll) { + if (!isCheckinRequest && dumpDetails) { pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **"); pw.flush(); } Debug.MemoryInfo mi = null; - if (dumpAll) { + if (dumpDetails) { try { - mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs); + mi = r.thread.dumpMemInfo(fd, isCheckinRequest, true, dumpDalvik, innerArgs); } catch (RemoteException e) { if (!isCheckinRequest) { pw.println("Got RemoteException!"); |