diff options
author | Dianne Hackborn <hackbod@google.com> | 2013-05-23 17:51:19 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2013-05-24 10:47:03 -0700 |
commit | 64770d16b0907a8e1ee81ef6c8fa398a6bdbee79 (patch) | |
tree | 8ba1bfe9832275e225701b2cf6e048d7a901023d /core | |
parent | dadfb9c9bfe17eb99a4891af0fe4eed7166f0b86 (diff) | |
download | frameworks_base-64770d16b0907a8e1ee81ef6c8fa398a6bdbee79.zip frameworks_base-64770d16b0907a8e1ee81ef6c8fa398a6bdbee79.tar.gz frameworks_base-64770d16b0907a8e1ee81ef6c8fa398a6bdbee79.tar.bz2 |
Some improvements to meminfo output.
- Rename "Swappable PSS" to "PSS Clean" which I think is what it
means and is consistent with the other memory metrics.
- Split at the top level the dalvik heap from other dalvik allocations,
so when you look on the dalvik allocations line things are consistent
with the allocator's data and it is clear what are app allocations vs.
other data in dalvik.
- Don't print lines that are all 0.
- Don't print the detailed Dalvik allocation data by default; add a new
option to have it printed.
Here's what a typical system process dump now looks like:
** MEMINFO in pid 6358 [system] **
Pss Pss Shared Private Shared Private Heap Heap Heap
Total Clean Dirty Dirty Clean Clean Size Alloc Free
------ ------ ------ ------ ------ ------ ------ ------ ------
Native Heap 0 0 0 0 0 0 6964 3599 2048
Dalvik Heap 7541 0 4344 7356 0 0 11768 11194 574
Dalvik Other 3553 0 2792 3448 0 0
Stack 28 0 8 28 0 0
Cursor 4 0 0 4 0 0
Ashmem 5 0 12 0 0 0
Other dev 4004 0 24 4000 0 4
.so mmap 3959 684 2500 2280 5468 684
.apk mmap 173 68 0 0 692 68
.dex mmap 4358 3068 0 0 9276 3068
Other mmap 60 0 8 8 244 36
Unknown 4387 0 508 4380 0 0
TOTAL 28072 3820 10196 21504 15680 3860 18732 14793 2622
Objects
Views: 10 ViewRootImpl: 1
AppContexts: 8 Activities: 0
Assets: 3 AssetManagers: 3
Local Binders: 176 Proxy Binders: 341
Death Recipients: 141
OpenSSL Sockets: 0
SQL
MEMORY_USED: 473
PAGECACHE_OVERFLOW: 98 MALLOC_SIZE: 62
DATABASES
pgsz dbsz Lookaside(b) cache Dbname
4 68 49 7/21/7 /data/data/com.android.providers.settings/databases/settings.db
4 20 17 0/13/1 /data/system/locksettings.db
4 20 21 96/14/2 /data/system/locksettings.db (1)
4 20 21 75/13/2 /data/system/locksettings.db (2)
4 80 29 4/17/3 /data/system/users/0/accounts.db
Change-Id: Ifd511a7baaa8808f82f39509a5a15c71c41d1bac
Diffstat (limited to 'core')
-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 |
5 files changed, 137 insertions, 106 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; |