Merge "incidentd: dumping native process mem info to proto."
This commit is contained in:
committed by
Android (Google) Code Review
commit
0b203b12a8
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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) {
|
||||
|
||||
@@ -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"
|
||||
];
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
@@ -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) {
|
||||
@@ -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();
|
||||
@@ -17298,54 +17298,59 @@ 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) != '-') {
|
||||
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);
|
||||
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) {
|
||||
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);
|
||||
final int pid = r.pid;
|
||||
if (!opts.isCheckinRequest && opts.dumpDetails) {
|
||||
pw.println("\n** MEMINFO in pid " + pid + " [" + 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(pw, mi, opts.isCheckinRequest, opts.dumpFullDetails,
|
||||
opts.dumpDalvik, opts.dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
|
||||
if (opts.isCheckinRequest) {
|
||||
pw.println();
|
||||
if (nativeProcs.size() > 0) {
|
||||
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);
|
||||
final int pid = r.pid;
|
||||
if (!opts.isCheckinRequest && opts.dumpDetails) {
|
||||
pw.println("\n** MEMINFO in pid " + pid + " [" + 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(pw, mi, opts.isCheckinRequest,
|
||||
opts.dumpFullDetails, opts.dumpDalvik, opts.dumpSummaryOnly,
|
||||
pid, r.baseName, 0, 0, 0, 0, 0, 0);
|
||||
if (opts.isCheckinRequest) {
|
||||
pw.println();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
pw.println("No process found for: " + innerArgs[0]);
|
||||
pw.println("No process found for: " + proc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
ProtoOutputStream proto = new ProtoOutputStream(fd);
|
||||
final long uptimeMs = SystemClock.uptimeMillis();
|
||||
final long realtimeMs = SystemClock.elapsedRealtime();
|
||||
final long[] tmpLong = new long[1];
|
||||
|
||||
// TODO: implement
|
||||
pw.println("Not yet implemented. Have a cookie instead! :]");
|
||||
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);
|
||||
|
||||
proto.flush();
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user