最近在做关于android memory的评估,其中核心命令是dumpsys meminfo的执行流程,其中很多数据的具体含义都不是很清楚,所以想做一个详细的研究由于对Java不是很熟,所以在描述过程中可能有些关于Java的执行细节不会描述的太清楚。
首先是framework部分的执行流程,通过搜索dumpsys meminfo的打印关键字得到:
dumpsys meminfo是从activityManagerservice.java的memBinder类的dump函数开始执行的,下面具体的介绍此函数的执行流程。
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
pw.println("Permission Denial: can't dump meminfo from from pid="
+ Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ " without permission " + android.Manifest.permission.DUMP);
return;
}
mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
}
这里可以看到dumpsys meminfo执行的主体函数,此时只讲dumpsys meminfo的整体执行流程,具体见代码的注释部分,后面会补上获取单独进程的memory信息的执行流程:
final void dumpApplicationMemoryUsage(FileDescriptor fd,
PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw){
boolean dumpDetails = false;
boolean dumpFullDetails = false;
boolean dumpDalvik = false;
boolean dumpSummaryOnly = false;
boolean oomOnly = false;
boolean isCompact = false;
boolean localOnly = false;
boolean packages = false;
int opti = 0;
while (opti < args.length) {//判断dumpsys meminfo的参数
String opt = args[opti];
if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
break;
}
opti++;
if ("-a".equals(opt)) {
dumpDetails = true;
dumpFullDetails = true;
dumpDalvik = true;
} else if ("-d".equals(opt)) {
dumpDalvik = true;
} else if ("-c".equals(opt)) {
isCompact = true;
} else if ("-s".equals(opt)) {
dumpDetails = true;
dumpSummaryOnly = true;
} else if ("--oom".equals(opt)) {
oomOnly = true;
} else if ("--local".equals(opt)) {
localOnly = true;
} else if ("--package".equals(opt)) {
packages = true;
} else if ("-h".equals(opt)) {
pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
pw.println(" -a: include all available information for each process.");
pw.println(" -d: include dalvik details.");
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(" --local: only collect details locally, don't call process.");
pw.println(" --package: interpret process arg as package, dumping all");
pw.println(" processes that have loaded that package.");
pw.println("If [process] is specified it can be the name or ");
pw.println("pid of a specific process to dump.");
return;
} else {
pw.println("Unknown argument: " + opt + "; use -h for help");
}
}
final boolean isCheckinRequest = scanArgs(args, "--checkin");
long uptime = SystemClock.uptimeMillis();
long realtime = SystemClock.elapsedRealtime();
final long[] tmpLong = new long[1];
ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);//获取当前所有运行的APP具体情况
if (procs == null) {//此时后台有进程运行,proc不为null,条件不执行
// No Java processes. Maybe they want to print a native process.
if (args != null && args.length > opti
&& args[opti].charAt(0) != '-') {
ArrayList<ProcessCpuTracker.Stats> nativeProcs
= new ArrayList<ProcessCpuTracker.Stats>();
updateCpuStatsNow();
int findPid = -1;
try {
findPid = Integer.parseInt(args[opti]);
} 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
&