Loading core/java/android/app/ActivityThread.java +163 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,7 @@ import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseIntArray; import android.util.SuperNotCalledException; import android.util.proto.ProtoOutputStream; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.ThreadedRenderer; Loading @@ -131,6 +132,7 @@ import com.android.internal.util.FastPrintWriter; import com.android.internal.util.IndentingPrintWriter; import com.android.org.conscrypt.OpenSSLSocketImpl; import com.android.org.conscrypt.TrustedCertificateStore; import com.android.server.am.proto.MemInfoProto; import dalvik.system.BaseDexClassLoader; import dalvik.system.CloseGuard; Loading Loading @@ -2259,6 +2261,167 @@ public final class ActivityThread extends ClientTransactionHandler { } } /** * Dump heap info to proto. * * @param hasSwappedOutPss determines whether to use dirtySwap or dirtySwapPss */ private static void dumpHeap(ProtoOutputStream proto, long fieldId, String name, int pss, int cleanPss, int sharedDirty, int privateDirty, int sharedClean, int privateClean, boolean hasSwappedOutPss, int dirtySwap, int dirtySwapPss) { final long token = proto.start(fieldId); proto.write(MemInfoProto.NativeProcess.MemoryInfo.NAME, name); proto.write(MemInfoProto.NativeProcess.MemoryInfo.TOTAL_PSS_KB, pss); proto.write(MemInfoProto.NativeProcess.MemoryInfo.CLEAN_PSS_KB, cleanPss); proto.write(MemInfoProto.NativeProcess.MemoryInfo.SHARED_DIRTY_KB, sharedDirty); proto.write(MemInfoProto.NativeProcess.MemoryInfo.PRIVATE_DIRTY_KB, privateDirty); proto.write(MemInfoProto.NativeProcess.MemoryInfo.SHARED_CLEAN_KB, sharedClean); proto.write(MemInfoProto.NativeProcess.MemoryInfo.PRIVATE_CLEAN_KB, privateClean); if (hasSwappedOutPss) { proto.write(MemInfoProto.NativeProcess.MemoryInfo.DIRTY_SWAP_PSS_KB, dirtySwapPss); } else { proto.write(MemInfoProto.NativeProcess.MemoryInfo.DIRTY_SWAP_KB, dirtySwap); } proto.end(token); } /** * Dump mem info data to proto. */ public static void dumpMemInfoTable(ProtoOutputStream proto, Debug.MemoryInfo memInfo, boolean dumpDalvik, boolean dumpSummaryOnly, long nativeMax, long nativeAllocated, long nativeFree, long dalvikMax, long dalvikAllocated, long dalvikFree) { if (!dumpSummaryOnly) { final long nhToken = proto.start(MemInfoProto.NativeProcess.NATIVE_HEAP); dumpHeap(proto, MemInfoProto.NativeProcess.HeapInfo.MEM_INFO, "Native Heap", memInfo.nativePss, memInfo.nativeSwappablePss, memInfo.nativeSharedDirty, memInfo.nativePrivateDirty, memInfo.nativeSharedClean, memInfo.nativePrivateClean, memInfo.hasSwappedOutPss, memInfo.nativeSwappedOut, memInfo.nativeSwappedOutPss); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_SIZE_KB, nativeMax); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_ALLOC_KB, nativeAllocated); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_FREE_KB, nativeFree); proto.end(nhToken); final long dvToken = proto.start(MemInfoProto.NativeProcess.DALVIK_HEAP); dumpHeap(proto, MemInfoProto.NativeProcess.HeapInfo.MEM_INFO, "Dalvik Heap", memInfo.dalvikPss, memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty, memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean, memInfo.dalvikPrivateClean, memInfo.hasSwappedOutPss, memInfo.dalvikSwappedOut, memInfo.dalvikSwappedOutPss); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_SIZE_KB, dalvikMax); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_ALLOC_KB, dalvikAllocated); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_FREE_KB, dalvikFree); proto.end(dvToken); 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; int otherSwappedOutPss = memInfo.otherSwappedOutPss; 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); final int mySwappedOutPss = memInfo.getOtherSwappedOutPss(i); if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 || mySharedClean != 0 || myPrivateClean != 0 || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) { dumpHeap(proto, MemInfoProto.NativeProcess.OTHER_HEAPS, Debug.MemoryInfo.getOtherLabel(i), myPss, mySwappablePss, mySharedDirty, myPrivateDirty, mySharedClean, myPrivateClean, memInfo.hasSwappedOutPss, mySwappedOut, mySwappedOutPss); otherPss -= myPss; otherSwappablePss -= mySwappablePss; otherSharedDirty -= mySharedDirty; otherPrivateDirty -= myPrivateDirty; otherSharedClean -= mySharedClean; otherPrivateClean -= myPrivateClean; otherSwappedOut -= mySwappedOut; otherSwappedOutPss -= mySwappedOutPss; } } dumpHeap(proto, MemInfoProto.NativeProcess.UNKNOWN_HEAP, "Unknown", otherPss, otherSwappablePss, otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean, memInfo.hasSwappedOutPss, otherSwappedOut, otherSwappedOutPss); final long tToken = proto.start(MemInfoProto.NativeProcess.TOTAL_HEAP); dumpHeap(proto, MemInfoProto.NativeProcess.HeapInfo.MEM_INFO, "TOTAL", memInfo.getTotalPss(), memInfo.getTotalSwappablePss(), memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(), memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(), memInfo.hasSwappedOutPss, memInfo.getTotalSwappedOut(), memInfo.getTotalSwappedOutPss()); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_SIZE_KB, nativeMax + dalvikMax); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_ALLOC_KB, nativeAllocated + dalvikAllocated); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_FREE_KB, nativeFree + dalvikFree); proto.end(tToken); if (dumpDalvik) { 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); final int mySwappedOutPss = memInfo.getOtherSwappedOutPss(i); if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 || mySharedClean != 0 || myPrivateClean != 0 || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) { dumpHeap(proto, MemInfoProto.NativeProcess.DALVIK_DETAILS, Debug.MemoryInfo.getOtherLabel(i), myPss, mySwappablePss, mySharedDirty, myPrivateDirty, mySharedClean, myPrivateClean, memInfo.hasSwappedOutPss, mySwappedOut, mySwappedOutPss); } } } } final long asToken = proto.start(MemInfoProto.NativeProcess.APP_SUMMARY); proto.write(MemInfoProto.NativeProcess.AppSummary.JAVA_HEAP_PSS_KB, memInfo.getSummaryJavaHeap()); proto.write(MemInfoProto.NativeProcess.AppSummary.NATIVE_HEAP_PSS_KB, memInfo.getSummaryNativeHeap()); proto.write(MemInfoProto.NativeProcess.AppSummary.CODE_PSS_KB, memInfo.getSummaryCode()); proto.write(MemInfoProto.NativeProcess.AppSummary.STACK_PSS_KB, memInfo.getSummaryStack()); proto.write(MemInfoProto.NativeProcess.AppSummary.GRAPHICS_PSS_KB, memInfo.getSummaryGraphics()); proto.write(MemInfoProto.NativeProcess.AppSummary.PRIVATE_OTHER_PSS_KB, memInfo.getSummaryPrivateOther()); proto.write(MemInfoProto.NativeProcess.AppSummary.SYSTEM_PSS_KB, memInfo.getSummarySystem()); if (memInfo.hasSwappedOutPss) { proto.write(MemInfoProto.NativeProcess.AppSummary.TOTAL_SWAP_PSS, memInfo.getSummaryTotalSwapPss()); } else { proto.write(MemInfoProto.NativeProcess.AppSummary.TOTAL_SWAP_PSS, memInfo.getSummaryTotalSwap()); } proto.end(asToken); } public void registerOnActivityPausedListener(Activity activity, OnActivityPausedListener listener) { synchronized (mOnPauseListeners) { Loading core/proto/android/os/incident.proto +5 −0 Original line number Diff line number Diff line Loading @@ -164,4 +164,9 @@ message IncidentProto { (section).type = SECTION_DUMPSYS, (section).args = "window --proto" ]; optional com.android.server.am.proto.MemInfoProto meminfo = 3018 [ (section).type = SECTION_DUMPSYS, (section).args = "meminfo --proto" ]; } core/proto/android/server/activitymanagerservice.proto +67 −4 Original line number Diff line number Diff line Loading @@ -16,16 +16,16 @@ syntax = "proto2"; package com.android.server.am.proto; import "frameworks/base/core/proto/android/app/notification.proto"; import "frameworks/base/core/proto/android/content/intent.proto"; import "frameworks/base/core/proto/android/server/intentresolver.proto"; import "frameworks/base/core/proto/android/server/windowmanagerservice.proto"; import "frameworks/base/core/proto/android/graphics/rect.proto"; import "frameworks/base/core/proto/android/os/looper.proto"; import "frameworks/base/core/proto/android/server/intentresolver.proto"; import "frameworks/base/core/proto/android/server/windowmanagerservice.proto"; import "frameworks/base/core/proto/android/util/common.proto"; package com.android.server.am.proto; option java_multiple_files = true; message ActivityManagerServiceProto { Loading Loading @@ -159,6 +159,69 @@ message BroadcastQueueProto { repeated BroadcastSummary historical_broadcasts_summary = 6; } message MemInfoProto { optional int64 uptime_duration_ms = 1; optional int64 elapsed_realtime_ms = 2; message NativeProcess { optional int32 pid = 1; optional string process_name = 2; message MemoryInfo { optional string name = 1; // The proportional set size for the heap. optional int32 total_pss_kb = 2; // The proportional set size that is swappable for the heap. optional int32 clean_pss_kb = 3; // The private dirty pages used by the heap. optional int32 shared_dirty_kb = 4; // The shared dirty pages used by the heap. optional int32 private_dirty_kb = 5; // The shared clean pages used by the heap. optional int32 shared_clean_kb = 6; // The private clean pages used by the heap. optional int32 private_clean_kb = 7; oneof dirty_swap { // The dirty the pages that have been swapped out. int32 dirty_swap_kb = 8; // The dirty the pages that have been swapped out, proportional. int32 dirty_swap_pss_kb = 9; } } message HeapInfo { optional MemoryInfo mem_info = 1; optional int32 heap_size_kb = 2; optional int32 heap_alloc_kb = 3; optional int32 heap_free_kb = 4; } optional HeapInfo native_heap = 3; optional HeapInfo dalvik_heap = 4; repeated MemoryInfo other_heaps = 5; optional HeapInfo unknown_heap = 6; // Summation of native_heap, dalvik_heap, and other_heaps. optional HeapInfo total_heap = 7; repeated MemoryInfo dalvik_details = 8; message AppSummary { optional int32 java_heap_pss_kb = 1; optional int32 native_heap_pss_kb = 2; optional int32 code_pss_kb = 3; optional int32 stack_pss_kb = 4; optional int32 graphics_pss_kb = 5; optional int32 private_other_pss_kb = 6; optional int32 system_pss_kb = 7; oneof total_swap { int32 total_swap_pss = 8; int32 total_swap_kb = 9; } } optional AppSummary app_summary = 9; } repeated NativeProcess native_processes = 3; } message StickyBroadcastProto { optional int32 user = 1; Loading services/core/java/com/android/server/am/ActivityManagerService.java +123 −56 Original line number Diff line number Diff line Loading @@ -417,6 +417,7 @@ import com.android.server.am.ActivityStack.ActivityState; import com.android.server.am.proto.ActivityManagerServiceProto; import com.android.server.am.proto.BroadcastProto; import com.android.server.am.proto.GrantUriProto; import com.android.server.am.proto.MemInfoProto; import com.android.server.am.proto.NeededUriGrantsProto; import com.android.server.am.proto.StickyBroadcastProto; import com.android.server.firewall.IntentFirewall; Loading Loading @@ -2569,14 +2570,13 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { if (asProto) return; mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", new String[] {"-a"}, false, null); dump(fd, pw, new String[] {"-a"}, asProto); } @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { if (asProto) return; mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); mActivityManagerService.dumpApplicationMemoryUsage( fd, pw, " ", args, false, null, asProto); } }; Loading Loading @@ -17207,8 +17207,8 @@ public class ActivityManagerService extends IActivityManager.Stub boolean dumpProto; } final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw, boolean asProto) { MemoryUsageDumpOptions opts = new MemoryUsageDumpOptions(); opts.dumpDetails = false; opts.dumpFullDetails = false; Loading @@ -17221,7 +17221,7 @@ public class ActivityManagerService extends IActivityManager.Stub opts.packages = false; opts.isCheckinRequest = false; opts.dumpSwapPss = false; opts.dumpProto = false; opts.dumpProto = asProto; int opti = 0; while (opti < args.length) { Loading Loading @@ -17289,7 +17289,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix, private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix, MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief, ArrayList<ProcessRecord> procs, PrintWriter categoryPw) { long uptime = SystemClock.uptimeMillis(); Loading @@ -17298,7 +17298,10 @@ public class ActivityManagerService extends IActivityManager.Stub if (procs == null) { // No Java processes. Maybe they want to print a native process. if (innerArgs.length > 0 && innerArgs[0].charAt(0) != '-') { String proc = "N/A"; if (innerArgs.length > 0) { proc = innerArgs[0]; if (proc.charAt(0) != '-') { ArrayList<ProcessCpuTracker.Stats> nativeProcs = new ArrayList<ProcessCpuTracker.Stats>(); updateCpuStatsNow(); Loading @@ -17318,8 +17321,8 @@ public class ActivityManagerService extends IActivityManager.Stub } } if (nativeProcs.size() > 0) { dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact); dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact); Debug.MemoryInfo mi = null; for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { final ProcessCpuTracker.Stats r = nativeProcs.get(i); Loading @@ -17336,8 +17339,9 @@ public class ActivityManagerService extends IActivityManager.Stub mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); mi.dalvikPrivateDirty = (int)tmpLong[0]; } ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0); ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0); if (opts.isCheckinRequest) { pw.println(); } Loading @@ -17345,7 +17349,8 @@ public class ActivityManagerService extends IActivityManager.Stub return; } } pw.println("No process found for: " + innerArgs[0]); } pw.println("No process found for: " + proc); return; } Loading Loading @@ -17768,15 +17773,77 @@ public class ActivityManagerService extends IActivityManager.Stub } } final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief, ArrayList<ProcessRecord> procs) { final long uptimeMs = SystemClock.uptimeMillis(); final long realtimeMs = SystemClock.elapsedRealtime(); final long[] tmpLong = new long[1]; if (procs == null) { // No Java processes. Maybe they want to print a native process. String proc = "N/A"; if (innerArgs.length > 0) { proc = innerArgs[0]; if (proc.charAt(0) != '-') { ArrayList<ProcessCpuTracker.Stats> nativeProcs = new ArrayList<ProcessCpuTracker.Stats>(); updateCpuStatsNow(); int findPid = -1; try { findPid = Integer.parseInt(innerArgs[0]); } catch (NumberFormatException e) { } synchronized (mProcessCpuTracker) { final int N = mProcessCpuTracker.countStats(); for (int i=0; i<N; i++) { ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); if (st.pid == findPid || (st.baseName != null && st.baseName.equals(innerArgs[0]))) { nativeProcs.add(st); } } } if (nativeProcs.size() > 0) { ProtoOutputStream proto = new ProtoOutputStream(fd); // TODO: implement pw.println("Not yet implemented. Have a cookie instead! :]"); proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs); proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs); Debug.MemoryInfo mi = null; for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { final ProcessCpuTracker.Stats r = nativeProcs.get(i); final int pid = r.pid; final long nToken = proto.start(MemInfoProto.NATIVE_PROCESSES); proto.write(MemInfoProto.NativeProcess.PID, pid); proto.write(MemInfoProto.NativeProcess.PROCESS_NAME, r.baseName); if (mi == null) { mi = new Debug.MemoryInfo(); } if (opts.dumpDetails || (!brief && !opts.oomOnly)) { Debug.getMemoryInfo(pid, mi); } else { mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); mi.dalvikPrivateDirty = (int)tmpLong[0]; } ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik, opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0); proto.end(nToken); } proto.flush(); return; } } } Log.d(TAG, "No process found for: " + innerArgs[0]); return; } // TODO: finish pw.println("Java processes aren't implemented yet. Have a coffee instead! :]"); } private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, Loading
core/java/android/app/ActivityThread.java +163 −0 Original line number Diff line number Diff line Loading @@ -108,6 +108,7 @@ import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseIntArray; import android.util.SuperNotCalledException; import android.util.proto.ProtoOutputStream; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.ThreadedRenderer; Loading @@ -131,6 +132,7 @@ import com.android.internal.util.FastPrintWriter; import com.android.internal.util.IndentingPrintWriter; import com.android.org.conscrypt.OpenSSLSocketImpl; import com.android.org.conscrypt.TrustedCertificateStore; import com.android.server.am.proto.MemInfoProto; import dalvik.system.BaseDexClassLoader; import dalvik.system.CloseGuard; Loading Loading @@ -2259,6 +2261,167 @@ public final class ActivityThread extends ClientTransactionHandler { } } /** * Dump heap info to proto. * * @param hasSwappedOutPss determines whether to use dirtySwap or dirtySwapPss */ private static void dumpHeap(ProtoOutputStream proto, long fieldId, String name, int pss, int cleanPss, int sharedDirty, int privateDirty, int sharedClean, int privateClean, boolean hasSwappedOutPss, int dirtySwap, int dirtySwapPss) { final long token = proto.start(fieldId); proto.write(MemInfoProto.NativeProcess.MemoryInfo.NAME, name); proto.write(MemInfoProto.NativeProcess.MemoryInfo.TOTAL_PSS_KB, pss); proto.write(MemInfoProto.NativeProcess.MemoryInfo.CLEAN_PSS_KB, cleanPss); proto.write(MemInfoProto.NativeProcess.MemoryInfo.SHARED_DIRTY_KB, sharedDirty); proto.write(MemInfoProto.NativeProcess.MemoryInfo.PRIVATE_DIRTY_KB, privateDirty); proto.write(MemInfoProto.NativeProcess.MemoryInfo.SHARED_CLEAN_KB, sharedClean); proto.write(MemInfoProto.NativeProcess.MemoryInfo.PRIVATE_CLEAN_KB, privateClean); if (hasSwappedOutPss) { proto.write(MemInfoProto.NativeProcess.MemoryInfo.DIRTY_SWAP_PSS_KB, dirtySwapPss); } else { proto.write(MemInfoProto.NativeProcess.MemoryInfo.DIRTY_SWAP_KB, dirtySwap); } proto.end(token); } /** * Dump mem info data to proto. */ public static void dumpMemInfoTable(ProtoOutputStream proto, Debug.MemoryInfo memInfo, boolean dumpDalvik, boolean dumpSummaryOnly, long nativeMax, long nativeAllocated, long nativeFree, long dalvikMax, long dalvikAllocated, long dalvikFree) { if (!dumpSummaryOnly) { final long nhToken = proto.start(MemInfoProto.NativeProcess.NATIVE_HEAP); dumpHeap(proto, MemInfoProto.NativeProcess.HeapInfo.MEM_INFO, "Native Heap", memInfo.nativePss, memInfo.nativeSwappablePss, memInfo.nativeSharedDirty, memInfo.nativePrivateDirty, memInfo.nativeSharedClean, memInfo.nativePrivateClean, memInfo.hasSwappedOutPss, memInfo.nativeSwappedOut, memInfo.nativeSwappedOutPss); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_SIZE_KB, nativeMax); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_ALLOC_KB, nativeAllocated); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_FREE_KB, nativeFree); proto.end(nhToken); final long dvToken = proto.start(MemInfoProto.NativeProcess.DALVIK_HEAP); dumpHeap(proto, MemInfoProto.NativeProcess.HeapInfo.MEM_INFO, "Dalvik Heap", memInfo.dalvikPss, memInfo.dalvikSwappablePss, memInfo.dalvikSharedDirty, memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean, memInfo.dalvikPrivateClean, memInfo.hasSwappedOutPss, memInfo.dalvikSwappedOut, memInfo.dalvikSwappedOutPss); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_SIZE_KB, dalvikMax); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_ALLOC_KB, dalvikAllocated); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_FREE_KB, dalvikFree); proto.end(dvToken); 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; int otherSwappedOutPss = memInfo.otherSwappedOutPss; 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); final int mySwappedOutPss = memInfo.getOtherSwappedOutPss(i); if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 || mySharedClean != 0 || myPrivateClean != 0 || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) { dumpHeap(proto, MemInfoProto.NativeProcess.OTHER_HEAPS, Debug.MemoryInfo.getOtherLabel(i), myPss, mySwappablePss, mySharedDirty, myPrivateDirty, mySharedClean, myPrivateClean, memInfo.hasSwappedOutPss, mySwappedOut, mySwappedOutPss); otherPss -= myPss; otherSwappablePss -= mySwappablePss; otherSharedDirty -= mySharedDirty; otherPrivateDirty -= myPrivateDirty; otherSharedClean -= mySharedClean; otherPrivateClean -= myPrivateClean; otherSwappedOut -= mySwappedOut; otherSwappedOutPss -= mySwappedOutPss; } } dumpHeap(proto, MemInfoProto.NativeProcess.UNKNOWN_HEAP, "Unknown", otherPss, otherSwappablePss, otherSharedDirty, otherPrivateDirty, otherSharedClean, otherPrivateClean, memInfo.hasSwappedOutPss, otherSwappedOut, otherSwappedOutPss); final long tToken = proto.start(MemInfoProto.NativeProcess.TOTAL_HEAP); dumpHeap(proto, MemInfoProto.NativeProcess.HeapInfo.MEM_INFO, "TOTAL", memInfo.getTotalPss(), memInfo.getTotalSwappablePss(), memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(), memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(), memInfo.hasSwappedOutPss, memInfo.getTotalSwappedOut(), memInfo.getTotalSwappedOutPss()); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_SIZE_KB, nativeMax + dalvikMax); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_ALLOC_KB, nativeAllocated + dalvikAllocated); proto.write(MemInfoProto.NativeProcess.HeapInfo.HEAP_FREE_KB, nativeFree + dalvikFree); proto.end(tToken); if (dumpDalvik) { 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); final int mySwappedOutPss = memInfo.getOtherSwappedOutPss(i); if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 || mySharedClean != 0 || myPrivateClean != 0 || (memInfo.hasSwappedOutPss ? mySwappedOutPss : mySwappedOut) != 0) { dumpHeap(proto, MemInfoProto.NativeProcess.DALVIK_DETAILS, Debug.MemoryInfo.getOtherLabel(i), myPss, mySwappablePss, mySharedDirty, myPrivateDirty, mySharedClean, myPrivateClean, memInfo.hasSwappedOutPss, mySwappedOut, mySwappedOutPss); } } } } final long asToken = proto.start(MemInfoProto.NativeProcess.APP_SUMMARY); proto.write(MemInfoProto.NativeProcess.AppSummary.JAVA_HEAP_PSS_KB, memInfo.getSummaryJavaHeap()); proto.write(MemInfoProto.NativeProcess.AppSummary.NATIVE_HEAP_PSS_KB, memInfo.getSummaryNativeHeap()); proto.write(MemInfoProto.NativeProcess.AppSummary.CODE_PSS_KB, memInfo.getSummaryCode()); proto.write(MemInfoProto.NativeProcess.AppSummary.STACK_PSS_KB, memInfo.getSummaryStack()); proto.write(MemInfoProto.NativeProcess.AppSummary.GRAPHICS_PSS_KB, memInfo.getSummaryGraphics()); proto.write(MemInfoProto.NativeProcess.AppSummary.PRIVATE_OTHER_PSS_KB, memInfo.getSummaryPrivateOther()); proto.write(MemInfoProto.NativeProcess.AppSummary.SYSTEM_PSS_KB, memInfo.getSummarySystem()); if (memInfo.hasSwappedOutPss) { proto.write(MemInfoProto.NativeProcess.AppSummary.TOTAL_SWAP_PSS, memInfo.getSummaryTotalSwapPss()); } else { proto.write(MemInfoProto.NativeProcess.AppSummary.TOTAL_SWAP_PSS, memInfo.getSummaryTotalSwap()); } proto.end(asToken); } public void registerOnActivityPausedListener(Activity activity, OnActivityPausedListener listener) { synchronized (mOnPauseListeners) { Loading
core/proto/android/os/incident.proto +5 −0 Original line number Diff line number Diff line Loading @@ -164,4 +164,9 @@ message IncidentProto { (section).type = SECTION_DUMPSYS, (section).args = "window --proto" ]; optional com.android.server.am.proto.MemInfoProto meminfo = 3018 [ (section).type = SECTION_DUMPSYS, (section).args = "meminfo --proto" ]; }
core/proto/android/server/activitymanagerservice.proto +67 −4 Original line number Diff line number Diff line Loading @@ -16,16 +16,16 @@ syntax = "proto2"; package com.android.server.am.proto; import "frameworks/base/core/proto/android/app/notification.proto"; import "frameworks/base/core/proto/android/content/intent.proto"; import "frameworks/base/core/proto/android/server/intentresolver.proto"; import "frameworks/base/core/proto/android/server/windowmanagerservice.proto"; import "frameworks/base/core/proto/android/graphics/rect.proto"; import "frameworks/base/core/proto/android/os/looper.proto"; import "frameworks/base/core/proto/android/server/intentresolver.proto"; import "frameworks/base/core/proto/android/server/windowmanagerservice.proto"; import "frameworks/base/core/proto/android/util/common.proto"; package com.android.server.am.proto; option java_multiple_files = true; message ActivityManagerServiceProto { Loading Loading @@ -159,6 +159,69 @@ message BroadcastQueueProto { repeated BroadcastSummary historical_broadcasts_summary = 6; } message MemInfoProto { optional int64 uptime_duration_ms = 1; optional int64 elapsed_realtime_ms = 2; message NativeProcess { optional int32 pid = 1; optional string process_name = 2; message MemoryInfo { optional string name = 1; // The proportional set size for the heap. optional int32 total_pss_kb = 2; // The proportional set size that is swappable for the heap. optional int32 clean_pss_kb = 3; // The private dirty pages used by the heap. optional int32 shared_dirty_kb = 4; // The shared dirty pages used by the heap. optional int32 private_dirty_kb = 5; // The shared clean pages used by the heap. optional int32 shared_clean_kb = 6; // The private clean pages used by the heap. optional int32 private_clean_kb = 7; oneof dirty_swap { // The dirty the pages that have been swapped out. int32 dirty_swap_kb = 8; // The dirty the pages that have been swapped out, proportional. int32 dirty_swap_pss_kb = 9; } } message HeapInfo { optional MemoryInfo mem_info = 1; optional int32 heap_size_kb = 2; optional int32 heap_alloc_kb = 3; optional int32 heap_free_kb = 4; } optional HeapInfo native_heap = 3; optional HeapInfo dalvik_heap = 4; repeated MemoryInfo other_heaps = 5; optional HeapInfo unknown_heap = 6; // Summation of native_heap, dalvik_heap, and other_heaps. optional HeapInfo total_heap = 7; repeated MemoryInfo dalvik_details = 8; message AppSummary { optional int32 java_heap_pss_kb = 1; optional int32 native_heap_pss_kb = 2; optional int32 code_pss_kb = 3; optional int32 stack_pss_kb = 4; optional int32 graphics_pss_kb = 5; optional int32 private_other_pss_kb = 6; optional int32 system_pss_kb = 7; oneof total_swap { int32 total_swap_pss = 8; int32 total_swap_kb = 9; } } optional AppSummary app_summary = 9; } repeated NativeProcess native_processes = 3; } message StickyBroadcastProto { optional int32 user = 1; Loading
services/core/java/com/android/server/am/ActivityManagerService.java +123 −56 Original line number Diff line number Diff line Loading @@ -417,6 +417,7 @@ import com.android.server.am.ActivityStack.ActivityState; import com.android.server.am.proto.ActivityManagerServiceProto; import com.android.server.am.proto.BroadcastProto; import com.android.server.am.proto.GrantUriProto; import com.android.server.am.proto.MemInfoProto; import com.android.server.am.proto.NeededUriGrantsProto; import com.android.server.am.proto.StickyBroadcastProto; import com.android.server.firewall.IntentFirewall; Loading Loading @@ -2569,14 +2570,13 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { if (asProto) return; mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", new String[] {"-a"}, false, null); dump(fd, pw, new String[] {"-a"}, asProto); } @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) { if (asProto) return; mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); mActivityManagerService.dumpApplicationMemoryUsage( fd, pw, " ", args, false, null, asProto); } }; Loading Loading @@ -17207,8 +17207,8 @@ public class ActivityManagerService extends IActivityManager.Stub boolean dumpProto; } final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw, boolean asProto) { MemoryUsageDumpOptions opts = new MemoryUsageDumpOptions(); opts.dumpDetails = false; opts.dumpFullDetails = false; Loading @@ -17221,7 +17221,7 @@ public class ActivityManagerService extends IActivityManager.Stub opts.packages = false; opts.isCheckinRequest = false; opts.dumpSwapPss = false; opts.dumpProto = false; opts.dumpProto = asProto; int opti = 0; while (opti < args.length) { Loading Loading @@ -17289,7 +17289,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix, private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix, MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief, ArrayList<ProcessRecord> procs, PrintWriter categoryPw) { long uptime = SystemClock.uptimeMillis(); Loading @@ -17298,7 +17298,10 @@ public class ActivityManagerService extends IActivityManager.Stub if (procs == null) { // No Java processes. Maybe they want to print a native process. if (innerArgs.length > 0 && innerArgs[0].charAt(0) != '-') { String proc = "N/A"; if (innerArgs.length > 0) { proc = innerArgs[0]; if (proc.charAt(0) != '-') { ArrayList<ProcessCpuTracker.Stats> nativeProcs = new ArrayList<ProcessCpuTracker.Stats>(); updateCpuStatsNow(); Loading @@ -17318,8 +17321,8 @@ public class ActivityManagerService extends IActivityManager.Stub } } if (nativeProcs.size() > 0) { dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact); dumpApplicationMemoryUsageHeader(pw, uptime, realtime, opts.isCheckinRequest, opts.isCompact); Debug.MemoryInfo mi = null; for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { final ProcessCpuTracker.Stats r = nativeProcs.get(i); Loading @@ -17336,8 +17339,9 @@ public class ActivityManagerService extends IActivityManager.Stub mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); mi.dalvikPrivateDirty = (int)tmpLong[0]; } ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0); ActivityThread.dumpMemInfoTable(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0); if (opts.isCheckinRequest) { pw.println(); } Loading @@ -17345,7 +17349,8 @@ public class ActivityManagerService extends IActivityManager.Stub return; } } pw.println("No process found for: " + innerArgs[0]); } pw.println("No process found for: " + proc); return; } Loading Loading @@ -17768,15 +17773,77 @@ public class ActivityManagerService extends IActivityManager.Stub } } final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, private final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, MemoryUsageDumpOptions opts, String[] innerArgs, boolean brief, ArrayList<ProcessRecord> procs) { final long uptimeMs = SystemClock.uptimeMillis(); final long realtimeMs = SystemClock.elapsedRealtime(); final long[] tmpLong = new long[1]; if (procs == null) { // No Java processes. Maybe they want to print a native process. String proc = "N/A"; if (innerArgs.length > 0) { proc = innerArgs[0]; if (proc.charAt(0) != '-') { ArrayList<ProcessCpuTracker.Stats> nativeProcs = new ArrayList<ProcessCpuTracker.Stats>(); updateCpuStatsNow(); int findPid = -1; try { findPid = Integer.parseInt(innerArgs[0]); } catch (NumberFormatException e) { } synchronized (mProcessCpuTracker) { final int N = mProcessCpuTracker.countStats(); for (int i=0; i<N; i++) { ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); if (st.pid == findPid || (st.baseName != null && st.baseName.equals(innerArgs[0]))) { nativeProcs.add(st); } } } if (nativeProcs.size() > 0) { ProtoOutputStream proto = new ProtoOutputStream(fd); // TODO: implement pw.println("Not yet implemented. Have a cookie instead! :]"); proto.write(MemInfoProto.UPTIME_DURATION_MS, uptimeMs); proto.write(MemInfoProto.ELAPSED_REALTIME_MS, realtimeMs); Debug.MemoryInfo mi = null; for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { final ProcessCpuTracker.Stats r = nativeProcs.get(i); final int pid = r.pid; final long nToken = proto.start(MemInfoProto.NATIVE_PROCESSES); proto.write(MemInfoProto.NativeProcess.PID, pid); proto.write(MemInfoProto.NativeProcess.PROCESS_NAME, r.baseName); if (mi == null) { mi = new Debug.MemoryInfo(); } if (opts.dumpDetails || (!brief && !opts.oomOnly)) { Debug.getMemoryInfo(pid, mi); } else { mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); mi.dalvikPrivateDirty = (int)tmpLong[0]; } ActivityThread.dumpMemInfoTable(proto, mi, opts.dumpDalvik, opts.dumpSummaryOnly, 0, 0, 0, 0, 0, 0); proto.end(nToken); } proto.flush(); return; } } } Log.d(TAG, "No process found for: " + innerArgs[0]); return; } // TODO: finish pw.println("Java processes aren't implemented yet. Have a coffee instead! :]"); } private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,