Loading core/java/android/app/ActivityThread.java +134 −107 Original line number Original line Diff line number Diff line Loading @@ -571,8 +571,6 @@ public final class ActivityThread { private native void dumpGraphicsInfo(FileDescriptor fd); private native void dumpGraphicsInfo(FileDescriptor fd); private class ApplicationThread extends ApplicationThreadNative { 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 static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s"; private int mLastProcessState = -1; private int mLastProcessState = -1; Loading Loading @@ -972,18 +970,18 @@ public final class ActivityThread { @Override @Override public void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin, 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); FileOutputStream fout = new FileOutputStream(fd); PrintWriter pw = new FastPrintWriter(fout); PrintWriter pw = new FastPrintWriter(fout); try { try { dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik); dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly); } finally { } finally { pw.flush(); pw.flush(); } } } } private void dumpMemInfo(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin, 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 nativeMax = Debug.getNativeHeapSize() / 1024; long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; long nativeFree = Debug.getNativeHeapFreeSize() / 1024; long nativeFree = Debug.getNativeHeapFreeSize() / 1024; Loading @@ -1007,7 +1005,8 @@ public final class ActivityThread { long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class); long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class); SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo(); 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", (mBoundApplication != null) ? mBoundApplication.processName : "unknown", nativeMax, nativeAllocated, nativeFree, nativeMax, nativeAllocated, nativeFree, dalvikMax, dalvikAllocated, dalvikFree); dalvikMax, dalvikAllocated, dalvikFree); Loading Loading @@ -1935,6 +1934,9 @@ public final class ActivityThread { = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s"; = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s"; private static final String HEAP_COLUMN private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s"; = "%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 // Formatting for checkin service - update version if row format changes private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 3; private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 3; Loading @@ -1944,7 +1946,8 @@ public final class ActivityThread { } } public static void dumpMemInfoTable(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin, 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 nativeMax, long nativeAllocated, long nativeFree, long dalvikMax, long dalvikAllocated, long dalvikFree) { long dalvikMax, long dalvikAllocated, long dalvikFree) { Loading Loading @@ -2025,7 +2028,7 @@ public final class ActivityThread { return; return; } } // otherwise, show human-readable format if (!dumpSummaryOnly) { if (dumpFullInfo) { if (dumpFullInfo) { printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private", printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private", "Shared", "Private", "Swapped", "Heap", "Heap", "Heap"); "Shared", "Private", "Swapped", "Heap", "Heap", "Heap"); Loading Loading @@ -2148,6 +2151,30 @@ public final class ActivityThread { } } } } 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, public void registerOnActivityPausedListener(Activity activity, OnActivityPausedListener listener) { OnActivityPausedListener listener) { synchronized (mOnPauseListeners) { synchronized (mOnPauseListeners) { Loading core/java/android/app/ApplicationThreadNative.java +5 −2 Original line number Original line Diff line number Diff line Loading @@ -529,10 +529,12 @@ public abstract class ApplicationThreadNative extends Binder boolean checkin = data.readInt() != 0; boolean checkin = data.readInt() != 0; boolean dumpInfo = data.readInt() != 0; boolean dumpInfo = data.readInt() != 0; boolean dumpDalvik = data.readInt() != 0; boolean dumpDalvik = data.readInt() != 0; boolean dumpSummaryOnly = data.readInt() != 0; String[] args = data.readStringArray(); String[] args = data.readStringArray(); if (fd != null) { if (fd != null) { try { try { dumpMemInfo(fd.getFileDescriptor(), mi, checkin, dumpInfo, dumpDalvik, args); dumpMemInfo(fd.getFileDescriptor(), mi, checkin, dumpInfo, dumpDalvik, dumpSummaryOnly, args); } finally { } finally { try { try { fd.close(); fd.close(); Loading Loading @@ -1248,7 +1250,7 @@ class ApplicationThreadProxy implements IApplicationThread { } } public void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin, 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 data = Parcel.obtain(); Parcel reply = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeInterfaceToken(IApplicationThread.descriptor); Loading @@ -1257,6 +1259,7 @@ class ApplicationThreadProxy implements IApplicationThread { data.writeInt(checkin ? 1 : 0); data.writeInt(checkin ? 1 : 0); data.writeInt(dumpInfo ? 1 : 0); data.writeInt(dumpInfo ? 1 : 0); data.writeInt(dumpDalvik ? 1 : 0); data.writeInt(dumpDalvik ? 1 : 0); data.writeInt(dumpSummaryOnly ? 1 : 0); data.writeStringArray(args); data.writeStringArray(args); mRemote.transact(DUMP_MEM_INFO_TRANSACTION, data, reply, 0); mRemote.transact(DUMP_MEM_INFO_TRANSACTION, data, reply, 0); reply.readException(); reply.readException(); Loading core/java/android/app/IApplicationThread.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -131,7 +131,7 @@ public interface IApplicationThread extends IInterface { void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) throws RemoteException; void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) throws RemoteException; void scheduleTrimMemory(int level) throws RemoteException; void scheduleTrimMemory(int level) throws RemoteException; void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin, boolean dumpInfo, 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 dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException; void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException; void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException; void unstableProviderDied(IBinder provider) throws RemoteException; void unstableProviderDied(IBinder provider) throws RemoteException; Loading core/java/android/os/Debug.java +211 −25 Original line number Original line Diff line number Diff line Loading @@ -168,6 +168,65 @@ public final class Debug /** @hide We may want to expose this, eventually. */ /** @hide We may want to expose this, eventually. */ public int otherSwappedOut; 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 */ /** @hide */ public static final int NUM_OTHER_STATS = 17; public static final int NUM_OTHER_STATS = 17; Loading Loading @@ -283,6 +342,11 @@ public final class Debug return otherStats[which*NUM_CATEGORIES + offsetPrivateClean]; return otherStats[which*NUM_CATEGORIES + offsetPrivateClean]; } } /** @hide */ public int getOtherPrivate(int which) { return getOtherPrivateClean(which) + getOtherPrivateDirty(which); } /** @hide */ /** @hide */ public int getOtherSharedClean(int which) { public int getOtherSharedClean(int which) { return otherStats[which*NUM_CATEGORIES + offsetSharedClean]; return otherStats[which*NUM_CATEGORIES + offsetSharedClean]; Loading @@ -296,35 +360,157 @@ public final class Debug /** @hide */ /** @hide */ public static String getOtherLabel(int which) { public static String getOtherLabel(int which) { switch (which) { switch (which) { case 0: return "Dalvik Other"; case OTHER_DALVIK_OTHER: return "Dalvik Other"; case 1: return "Stack"; case OTHER_STACK: return "Stack"; case 2: return "Cursor"; case OTHER_CURSOR: return "Cursor"; case 3: return "Ashmem"; case OTHER_ASHMEM: return "Ashmem"; case 4: return "Gfx dev"; case OTHER_GL_DEV: return "Gfx dev"; case 5: return "Other dev"; case OTHER_UNKNOWN_DEV: return "Other dev"; case 6: return ".so mmap"; case OTHER_SO: return ".so mmap"; case 7: return ".jar mmap"; case OTHER_JAR: return ".jar mmap"; case 8: return ".apk mmap"; case OTHER_APK: return ".apk mmap"; case 9: return ".ttf mmap"; case OTHER_TTF: return ".ttf mmap"; case 10: return ".dex mmap"; case OTHER_DEX: return ".dex mmap"; case 11: return ".oat mmap"; case OTHER_OAT: return ".oat mmap"; case 12: return ".art mmap"; case OTHER_ART: return ".art mmap"; case 13: return "Other mmap"; case OTHER_UNKNOWN_MAP: return "Other mmap"; case 14: return "EGL mtrack"; case OTHER_GRAPHICS: return "EGL mtrack"; case 15: return "GL mtrack"; case OTHER_GL: return "GL mtrack"; case 16: return "Other mtrack"; case OTHER_OTHER_MEMTRACK: return "Other mtrack"; case 17: return ".Heap"; case OTHER_DALVIK_NORMAL: return ".Heap"; case 18: return ".LOS"; case OTHER_DALVIK_LARGE: return ".LOS"; case 19: return ".LinearAlloc"; case OTHER_DALVIK_LINEARALLOC: return ".LinearAlloc"; case 20: return ".GC"; case OTHER_DALVIK_ACCOUNTING: return ".GC"; case 21: return ".JITCache"; case OTHER_DALVIK_CODE_CACHE: return ".JITCache"; case 22: return ".Zygote"; case OTHER_DALVIK_ZYGOTE: return ".Zygote"; case 23: return ".NonMoving"; case OTHER_DALVIK_NON_MOVING: return ".NonMoving"; case 24: return ".IndirectRef"; case OTHER_DALVIK_INDIRECT_REFERENCE_TABLE: return ".IndirectRef"; default: return "????"; 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() { public int describeContents() { return 0; return 0; } } Loading services/core/java/com/android/server/am/ActivityManagerService.java +9 −4 Original line number Original line Diff line number Diff line Loading @@ -14121,6 +14121,7 @@ public final class ActivityManagerService extends ActivityManagerNative boolean dumpDetails = false; boolean dumpDetails = false; boolean dumpFullDetails = false; boolean dumpFullDetails = false; boolean dumpDalvik = false; boolean dumpDalvik = false; boolean dumpSummaryOnly = false; boolean oomOnly = false; boolean oomOnly = false; boolean isCompact = false; boolean isCompact = false; boolean localOnly = false; boolean localOnly = false; Loading @@ -14141,6 +14142,9 @@ public final class ActivityManagerService extends ActivityManagerNative dumpDalvik = true; dumpDalvik = true; } else if ("-c".equals(opt)) { } else if ("-c".equals(opt)) { isCompact = true; isCompact = true; } else if ("-s".equals(opt)) { dumpDetails = true; dumpSummaryOnly = true; } else if ("--oom".equals(opt)) { } else if ("--oom".equals(opt)) { oomOnly = true; oomOnly = true; } else if ("--local".equals(opt)) { } else if ("--local".equals(opt)) { Loading @@ -14148,10 +14152,11 @@ public final class ActivityManagerService extends ActivityManagerNative } else if ("--package".equals(opt)) { } else if ("--package".equals(opt)) { packages = true; packages = true; } else if ("-h".equals(opt)) { } 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(" -a: include all available information for each process."); pw.println(" -d: include dalvik details."); pw.println(" -d: include dalvik details."); pw.println(" -c: dump in a compact machine-parseable representation."); 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(" --oom: only show processes organized by oom adj."); pw.println(" --local: only collect details locally, don't call process."); pw.println(" --local: only collect details locally, don't call process."); pw.println(" --package: interpret process arg as package, dumping all"); pw.println(" --package: interpret process arg as package, dumping all"); Loading Loading @@ -14212,7 +14217,7 @@ public final class ActivityManagerService extends ActivityManagerNative mi.dalvikPrivateDirty = (int)tmpLong[0]; mi.dalvikPrivateDirty = (int)tmpLong[0]; } } ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 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) { if (isCheckinRequest) { pw.println(); pw.println(); } } Loading Loading @@ -14278,7 +14283,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (dumpDetails) { if (dumpDetails) { if (localOnly) { if (localOnly) { ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 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) { if (isCheckinRequest) { pw.println(); pw.println(); } } Loading @@ -14286,7 +14291,7 @@ public final class ActivityManagerService extends ActivityManagerNative try { try { pw.flush(); pw.flush(); thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, dumpDalvik, innerArgs); dumpDalvik, dumpSummaryOnly, innerArgs); } catch (RemoteException e) { } catch (RemoteException e) { if (!isCheckinRequest) { if (!isCheckinRequest) { pw.println("Got RemoteException!"); pw.println("Got RemoteException!"); Loading
core/java/android/app/ActivityThread.java +134 −107 Original line number Original line Diff line number Diff line Loading @@ -571,8 +571,6 @@ public final class ActivityThread { private native void dumpGraphicsInfo(FileDescriptor fd); private native void dumpGraphicsInfo(FileDescriptor fd); private class ApplicationThread extends ApplicationThreadNative { 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 static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s"; private int mLastProcessState = -1; private int mLastProcessState = -1; Loading Loading @@ -972,18 +970,18 @@ public final class ActivityThread { @Override @Override public void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin, 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); FileOutputStream fout = new FileOutputStream(fd); PrintWriter pw = new FastPrintWriter(fout); PrintWriter pw = new FastPrintWriter(fout); try { try { dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik); dumpMemInfo(pw, mem, checkin, dumpFullInfo, dumpDalvik, dumpSummaryOnly); } finally { } finally { pw.flush(); pw.flush(); } } } } private void dumpMemInfo(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin, 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 nativeMax = Debug.getNativeHeapSize() / 1024; long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; long nativeFree = Debug.getNativeHeapFreeSize() / 1024; long nativeFree = Debug.getNativeHeapFreeSize() / 1024; Loading @@ -1007,7 +1005,8 @@ public final class ActivityThread { long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class); long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class); SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo(); 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", (mBoundApplication != null) ? mBoundApplication.processName : "unknown", nativeMax, nativeAllocated, nativeFree, nativeMax, nativeAllocated, nativeFree, dalvikMax, dalvikAllocated, dalvikFree); dalvikMax, dalvikAllocated, dalvikFree); Loading Loading @@ -1935,6 +1934,9 @@ public final class ActivityThread { = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s"; = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s %8s"; private static final String HEAP_COLUMN private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s"; = "%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 // Formatting for checkin service - update version if row format changes private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 3; private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 3; Loading @@ -1944,7 +1946,8 @@ public final class ActivityThread { } } public static void dumpMemInfoTable(PrintWriter pw, Debug.MemoryInfo memInfo, boolean checkin, 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 nativeMax, long nativeAllocated, long nativeFree, long dalvikMax, long dalvikAllocated, long dalvikFree) { long dalvikMax, long dalvikAllocated, long dalvikFree) { Loading Loading @@ -2025,7 +2028,7 @@ public final class ActivityThread { return; return; } } // otherwise, show human-readable format if (!dumpSummaryOnly) { if (dumpFullInfo) { if (dumpFullInfo) { printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private", printRow(pw, HEAP_FULL_COLUMN, "", "Pss", "Pss", "Shared", "Private", "Shared", "Private", "Swapped", "Heap", "Heap", "Heap"); "Shared", "Private", "Swapped", "Heap", "Heap", "Heap"); Loading Loading @@ -2148,6 +2151,30 @@ public final class ActivityThread { } } } } 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, public void registerOnActivityPausedListener(Activity activity, OnActivityPausedListener listener) { OnActivityPausedListener listener) { synchronized (mOnPauseListeners) { synchronized (mOnPauseListeners) { Loading
core/java/android/app/ApplicationThreadNative.java +5 −2 Original line number Original line Diff line number Diff line Loading @@ -529,10 +529,12 @@ public abstract class ApplicationThreadNative extends Binder boolean checkin = data.readInt() != 0; boolean checkin = data.readInt() != 0; boolean dumpInfo = data.readInt() != 0; boolean dumpInfo = data.readInt() != 0; boolean dumpDalvik = data.readInt() != 0; boolean dumpDalvik = data.readInt() != 0; boolean dumpSummaryOnly = data.readInt() != 0; String[] args = data.readStringArray(); String[] args = data.readStringArray(); if (fd != null) { if (fd != null) { try { try { dumpMemInfo(fd.getFileDescriptor(), mi, checkin, dumpInfo, dumpDalvik, args); dumpMemInfo(fd.getFileDescriptor(), mi, checkin, dumpInfo, dumpDalvik, dumpSummaryOnly, args); } finally { } finally { try { try { fd.close(); fd.close(); Loading Loading @@ -1248,7 +1250,7 @@ class ApplicationThreadProxy implements IApplicationThread { } } public void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin, 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 data = Parcel.obtain(); Parcel reply = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeInterfaceToken(IApplicationThread.descriptor); Loading @@ -1257,6 +1259,7 @@ class ApplicationThreadProxy implements IApplicationThread { data.writeInt(checkin ? 1 : 0); data.writeInt(checkin ? 1 : 0); data.writeInt(dumpInfo ? 1 : 0); data.writeInt(dumpInfo ? 1 : 0); data.writeInt(dumpDalvik ? 1 : 0); data.writeInt(dumpDalvik ? 1 : 0); data.writeInt(dumpSummaryOnly ? 1 : 0); data.writeStringArray(args); data.writeStringArray(args); mRemote.transact(DUMP_MEM_INFO_TRANSACTION, data, reply, 0); mRemote.transact(DUMP_MEM_INFO_TRANSACTION, data, reply, 0); reply.readException(); reply.readException(); Loading
core/java/android/app/IApplicationThread.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -131,7 +131,7 @@ public interface IApplicationThread extends IInterface { void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) throws RemoteException; void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) throws RemoteException; void scheduleTrimMemory(int level) throws RemoteException; void scheduleTrimMemory(int level) throws RemoteException; void dumpMemInfo(FileDescriptor fd, Debug.MemoryInfo mem, boolean checkin, boolean dumpInfo, 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 dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException; void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException; void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException; void unstableProviderDied(IBinder provider) throws RemoteException; void unstableProviderDied(IBinder provider) throws RemoteException; Loading
core/java/android/os/Debug.java +211 −25 Original line number Original line Diff line number Diff line Loading @@ -168,6 +168,65 @@ public final class Debug /** @hide We may want to expose this, eventually. */ /** @hide We may want to expose this, eventually. */ public int otherSwappedOut; 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 */ /** @hide */ public static final int NUM_OTHER_STATS = 17; public static final int NUM_OTHER_STATS = 17; Loading Loading @@ -283,6 +342,11 @@ public final class Debug return otherStats[which*NUM_CATEGORIES + offsetPrivateClean]; return otherStats[which*NUM_CATEGORIES + offsetPrivateClean]; } } /** @hide */ public int getOtherPrivate(int which) { return getOtherPrivateClean(which) + getOtherPrivateDirty(which); } /** @hide */ /** @hide */ public int getOtherSharedClean(int which) { public int getOtherSharedClean(int which) { return otherStats[which*NUM_CATEGORIES + offsetSharedClean]; return otherStats[which*NUM_CATEGORIES + offsetSharedClean]; Loading @@ -296,35 +360,157 @@ public final class Debug /** @hide */ /** @hide */ public static String getOtherLabel(int which) { public static String getOtherLabel(int which) { switch (which) { switch (which) { case 0: return "Dalvik Other"; case OTHER_DALVIK_OTHER: return "Dalvik Other"; case 1: return "Stack"; case OTHER_STACK: return "Stack"; case 2: return "Cursor"; case OTHER_CURSOR: return "Cursor"; case 3: return "Ashmem"; case OTHER_ASHMEM: return "Ashmem"; case 4: return "Gfx dev"; case OTHER_GL_DEV: return "Gfx dev"; case 5: return "Other dev"; case OTHER_UNKNOWN_DEV: return "Other dev"; case 6: return ".so mmap"; case OTHER_SO: return ".so mmap"; case 7: return ".jar mmap"; case OTHER_JAR: return ".jar mmap"; case 8: return ".apk mmap"; case OTHER_APK: return ".apk mmap"; case 9: return ".ttf mmap"; case OTHER_TTF: return ".ttf mmap"; case 10: return ".dex mmap"; case OTHER_DEX: return ".dex mmap"; case 11: return ".oat mmap"; case OTHER_OAT: return ".oat mmap"; case 12: return ".art mmap"; case OTHER_ART: return ".art mmap"; case 13: return "Other mmap"; case OTHER_UNKNOWN_MAP: return "Other mmap"; case 14: return "EGL mtrack"; case OTHER_GRAPHICS: return "EGL mtrack"; case 15: return "GL mtrack"; case OTHER_GL: return "GL mtrack"; case 16: return "Other mtrack"; case OTHER_OTHER_MEMTRACK: return "Other mtrack"; case 17: return ".Heap"; case OTHER_DALVIK_NORMAL: return ".Heap"; case 18: return ".LOS"; case OTHER_DALVIK_LARGE: return ".LOS"; case 19: return ".LinearAlloc"; case OTHER_DALVIK_LINEARALLOC: return ".LinearAlloc"; case 20: return ".GC"; case OTHER_DALVIK_ACCOUNTING: return ".GC"; case 21: return ".JITCache"; case OTHER_DALVIK_CODE_CACHE: return ".JITCache"; case 22: return ".Zygote"; case OTHER_DALVIK_ZYGOTE: return ".Zygote"; case 23: return ".NonMoving"; case OTHER_DALVIK_NON_MOVING: return ".NonMoving"; case 24: return ".IndirectRef"; case OTHER_DALVIK_INDIRECT_REFERENCE_TABLE: return ".IndirectRef"; default: return "????"; 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() { public int describeContents() { return 0; return 0; } } Loading
services/core/java/com/android/server/am/ActivityManagerService.java +9 −4 Original line number Original line Diff line number Diff line Loading @@ -14121,6 +14121,7 @@ public final class ActivityManagerService extends ActivityManagerNative boolean dumpDetails = false; boolean dumpDetails = false; boolean dumpFullDetails = false; boolean dumpFullDetails = false; boolean dumpDalvik = false; boolean dumpDalvik = false; boolean dumpSummaryOnly = false; boolean oomOnly = false; boolean oomOnly = false; boolean isCompact = false; boolean isCompact = false; boolean localOnly = false; boolean localOnly = false; Loading @@ -14141,6 +14142,9 @@ public final class ActivityManagerService extends ActivityManagerNative dumpDalvik = true; dumpDalvik = true; } else if ("-c".equals(opt)) { } else if ("-c".equals(opt)) { isCompact = true; isCompact = true; } else if ("-s".equals(opt)) { dumpDetails = true; dumpSummaryOnly = true; } else if ("--oom".equals(opt)) { } else if ("--oom".equals(opt)) { oomOnly = true; oomOnly = true; } else if ("--local".equals(opt)) { } else if ("--local".equals(opt)) { Loading @@ -14148,10 +14152,11 @@ public final class ActivityManagerService extends ActivityManagerNative } else if ("--package".equals(opt)) { } else if ("--package".equals(opt)) { packages = true; packages = true; } else if ("-h".equals(opt)) { } 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(" -a: include all available information for each process."); pw.println(" -d: include dalvik details."); pw.println(" -d: include dalvik details."); pw.println(" -c: dump in a compact machine-parseable representation."); 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(" --oom: only show processes organized by oom adj."); pw.println(" --local: only collect details locally, don't call process."); pw.println(" --local: only collect details locally, don't call process."); pw.println(" --package: interpret process arg as package, dumping all"); pw.println(" --package: interpret process arg as package, dumping all"); Loading Loading @@ -14212,7 +14217,7 @@ public final class ActivityManagerService extends ActivityManagerNative mi.dalvikPrivateDirty = (int)tmpLong[0]; mi.dalvikPrivateDirty = (int)tmpLong[0]; } } ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 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) { if (isCheckinRequest) { pw.println(); pw.println(); } } Loading Loading @@ -14278,7 +14283,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (dumpDetails) { if (dumpDetails) { if (localOnly) { if (localOnly) { ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 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) { if (isCheckinRequest) { pw.println(); pw.println(); } } Loading @@ -14286,7 +14291,7 @@ public final class ActivityManagerService extends ActivityManagerNative try { try { pw.flush(); pw.flush(); thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, dumpDalvik, innerArgs); dumpDalvik, dumpSummaryOnly, innerArgs); } catch (RemoteException e) { } catch (RemoteException e) { if (!isCheckinRequest) { if (!isCheckinRequest) { pw.println("Got RemoteException!"); pw.println("Got RemoteException!");