Android CPU使用率:top和dump cpuinfo的不同
CPU是系统非常重要的资源,在Android中,查看CPU使用情况,可以使用top命令和dump cpuinfo。我记得很久以前,就发现这两者存在不同,初步猜测应该是算法上存在差异。最近需要采集应用CPU的使用率,看了一下两种CPU的计算方法。
1、top
top是比较经典的CPU计算方法,top的代码在androidm/system/core/toolbox/top.c下面,输出process的cpu使用率在print_procs里面:
static void print_procs(void) {
...
for (i = 0; i < num_new_procs; i++) {
if (new_procs[i]) {
old_proc = find_old_proc(new_procs[i]->pid, new_procs[i]->tid);
if (old_proc) {
new_procs[i]->delta_utime = new_procs[i]->utime - old_proc->utime;
new_procs[i]->delta_stime = new_procs[i]->stime - old_proc->stime;
} else {
new_procs[i]->delta_utime = 0;
new_procs[i]->delta_stime = 0;
}
new_procs[i]->delta_time = new_procs[i]->delta_utime + new_procs[i]->delta_stime;
}
}
total_delta_time = (new_cpu.utime + new_cpu.ntime + new_cpu.stime + new_cpu.itime
+ new_cpu.iowtime + new_cpu.irqtime + new_cpu.sirqtime)
- (old_cpu.utime + old_cpu.ntime + old_cpu.stime + old_cpu.itime
+ old_cpu.iowtime + old_cpu.irqtime + old_cpu.sirqtime);
...
if (!threads) {
printf("%5d %2d %3" PRIu64 "%% %c %5d %6" PRIu64 "K %6" PRIu64 "K %3s %-8.8s %s\n",
proc->pid, proc->prs, proc->delta_time * 100 / total_delta_time, proc->state, proc->num_threads,
proc->vss / 1024, proc->rss * getpagesize() / 1024, proc->policy, user_str, proc->name[0] != 0 ? proc->name : proc->tname);
} else {
printf("%5d %5d %2d %3" PRIu64 "%% %c %6" PRIu64 "K %6" PRIu64 "K %3s %-8.8s %-15s %s\n",
proc->pid, proc->tid, proc->prs, proc->delta_time * 100 / total_delta_time, proc->state,
proc->vss / 1024, proc->rss * getpagesize() / 1024, proc->policy, user_str, proc->tname, proc->name);
}
...
}
CPU的计算是proc->delta_time * 100 / total_delta_time。
先看total_delta_time由:
total_delta_time = (new_cpu.utime + new_cpu.ntime + new_cpu.stime + new_cpu.itime
+ new_cpu.iowtime + new_cpu.irqtime + new_cpu.sirqtime)
- (old_cpu.utime + old_cpu.ntime + old_cpu.stime + old_cpu.itime
+ old_cpu.iowtime + old_cpu.irqtime + old_cpu.sirqtime);
而这些变量的值,是在read_procs通过读取/proc/stat的jiffies得到:
static void read_procs(void) {
...
proc_dir = opendir("/proc");
if (!proc_dir) die("Could not open /proc.\n");
new_procs = calloc(INIT_PROCS * (threads ? THREAD_MULT : 1), sizeof(struct proc_info *));
num_new_procs = INIT_PROCS * (threads ? THREAD_MULT : 1);
file = fopen("/proc/stat", "r");
if (!file) die("Could not open /proc/stat.\n");
fscanf(file, "cpu %lu %lu %lu %lu %lu %lu %lu", &new_cpu.utime, &new_cpu.ntime, &new_cpu.stime,
&new_cpu.itime, &new_cpu.iowtime, &new_cpu.irqtime, &new_cpu.sirqtime);
fclose(file);
而proc->delta_time是两次读取/proc/pid/stat相减得到:
static int read_stat(char *filename, struct proc_info *proc) {
...
/* Scan rest of string. */
sscanf(close_paren + 1,
" %c " "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
"%" SCNu64
"%" SCNu64 "%*d %*d %*d %*d %*d %*d %*d "
"%" SCNu64
"%" SCNu64 "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
"%d",
&proc->state,
&proc->utime,
&proc->stime,
&proc->vss,
&proc->rss,
&proc->prs);
return 0;
}
可见,top是一段时间内,计算process的cpu jiffies与总的cpu jiffies差值得到。
2、dump cpuinfo
dump cpuinfo是Android特有的命令(我一直都android的各种dump、trace非常感兴趣,快玩物丧志了。。。)。dump cpuinfo命令的实现在androidm/frameworks/base/core/Java/com/android/internal/os/ProcessCpuTracker.java类里面,方法是printCurrentState:
final public String printCurrentState(long now) {
...
int N = mWorkingProcs.size();
for (int i=0; i<N; i++) {
Stats st = mWorkingProcs.get(i);
printProcessCPU(pw, st.added ? " +" : (st.removed ? " -": " "),
st.pid, st.name, (int)st.rel_uptime,
st.rel_utime, st.rel_stime, 0, 0, 0, st.rel_minfaults, st.rel_majfaults);
if (!st.removed && st.workingThreads != null) {
int M = st.workingThreads.size();
for (int j=0; j<M; j++) {
Stats tst = st.workingThreads.get(j);
printProcessCPU(pw,
tst.added ? " +" : (tst.removed ? " -": " "),
tst.pid, tst.name, (int)st.rel_uptime,
tst.rel_utime, tst.rel_stime, 0, 0, 0, 0, 0);
}
}
}
...
}
而printProcessCPU输出process CPU的使用情况:
private void printProcessCPU(PrintWriter pw, String prefix, int pid, String label,
int totalTime, int user, int system, int iowait, int irq, int softIrq,
int minFaults, int majFaults) {
pw.print(prefix);
if (totalTime == 0) totalTime = 1;
printRatio(pw, user+system+iowait+irq+softIrq, totalTime);
...
}
user+system+iowait+irq+softIrq 比totalTime。
看下st个变量的赋值,在collectStats里面:
private int[] collectStats(String statsFile, int parentPid, boolean first,
int[] curPids, ArrayList<Stats> allProcs) {
int[] pids = Process.getPids(statsFile, curPids);
...
final long uptime = SystemClock.uptimeMillis();
final long[] procStats = mProcessStatsData;
if (!Process.readProcFile(st.statFile.toString(),
PROCESS_STATS_FORMAT, null, procStats, null)) {
continue;
}
...
if (DEBUG) Slog.v("Load", "Stats changed " + st.name + " pid=" + st.pid
+ " utime=" + utime + "-" + st.base_utime
+ " stime=" + stime + "-" + st.base_stime
+ " minfaults=" + minfaults + "-" + st.base_minfaults
+ " majfaults=" + majfaults + "-" + st.base_majfaults);
st.rel_uptime = uptime - st.base_uptime;
st.base_uptime = uptime;
st.rel_utime = (int)(utime - st.base_utime);
st.rel_stime = (int)(stime - st.base_stime);
st.base_utime = utime;
st.base_stime = stime;
st.rel_minfaults = (int)(minfaults - st.base_minfaults);
st.rel_majfaults = (int)(majfaults - st.base_majfaults);
st.base_minfaults = minfaults;
st.base_majfaults = majfaults;
st.working = true;
...
}
st.rel_utime 和 st.rel_stime还是通过读/proc/pid/stat相减得到,而st.rel_uptime却是通过 SystemClock.uptimeMillis()差值,并不是跟top一样,通过得到总CPU jiffies。
看到这,也就能明白,top跟dump cpuinfo的区别在于:top分母有的是总测CPU jiffies,而dump cpuinfo是uptime,是时间,而并非jiffies,也能解释为什么top出来的cpu,大部分时间会比dump cpuinfo的原因。
Android CPU使用率:top和dump cpuinfo的不同的更多相关文章
- [转] 查看CPU使用率 top命令详解
一 top是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前 台,直到用户终止该程序为止. 比较准确的说,top命令提供了实时的对系统处理器的状态监视.它将显示 ...
- Linux下查看CPU使用率 --- top命令的使用
在系统维护的过程中,随时可能有需要查看 CPU 使用率,并根据相应信息分析系统状况的需要.在 CentOS 中,可以通过 top 命令来查看 CPU 使用状况.运行 top 命令后,CPU 使用状态会 ...
- 某个应用的CPU使用率居然达到100%,我该怎么办?
> 本文是通过学习极客时间专栏<Linux性能优化实战>05 | 基础篇:某个应用的CPU使用率居然达到100%,我该怎么办? ## CPU 使用率 *** 为了维护 CPU 时间, ...
- Android获取cpu使用率,剩余内存和硬盘容量
1.内存信息 在proc/meminfo下有具体的内存使用情况,我这里获取的内存信息就是从这个文件中获取的.获取到具体的内存信息后依据我自己的需求,从bufferdreader中单独抽取出来了剩余的内 ...
- centOs 查看系统cpu使用率等--top
原文:centOs 查看系统cpu使用率等--top 在系统维护的过程中,随时可能有需要查看 CPU 使用率,并根据相应信息分析系统状况的需要.在 CentOS 中,可以通过 top 命令来查看 CP ...
- 在Linux中通过Top运行进程查找最高内存和CPU使用率
按内存使用情况查找前15个进程,在批处理模式下为"top" 使用top命令查看有关当前状态,系统使用情况的更详细信息:正常运行时间,负载平均值和进程总数. 分类:Linux命令操作 ...
- Linux平台Cpu使用率的计算
proc文件系统 /proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间.它以文件系统的方式为内核与进程提供通信的接口.用户和应用程序可以通过/proc得到系统的信息,并可以改变内核的 ...
- Java进程CPU使用率高排查
Java进程CPU使用率高排查 生产java应用,CPU使用率一直很高,经常达到100%,通过以下步骤完美解决,分享一下.1.jps 获取Java进程的PID.2.jstack pid >> ...
- 查看线程linux cpu使用率
Linux下如何查看高CPU占用率线程 LINUX CPU利用率计算 转 http://www.cnblogs.com/lidabo/p/4738113.html目录(?)[-] proc文件系统 p ...
随机推荐
- 深入理解java:2.3.2. 并发编程concurrent包 之重入锁/读写锁/条件锁
重入锁 Java中的重入锁(即ReentrantLock) 与JVM内置锁(即synchronized)一样,是一种排它锁. ReentrantLock提供了多样化的同步,比如有时间限制的同步(定 ...
- spring -boot定时任务 quartz 基于 MethodInvokingJobDetailFactoryBean 实现
spring 定时任务 quartz 基于 MethodInvokingJobDetailFactoryBean 实现 依赖包 如下 <dependencies> <depende ...
- 第四周课程总结与第二次实验报告(Java简单类与对象)
1.写一个名为Rectangle的类表示矩形.其属性包括宽width.高height和颜色color,width和height都是double型的,而color则是String类型的.要求该类具有: ...
- ball小游戏
2019第三次课程设计实验报告 一.实验项目 -- ball 二.实验功能描述: 玩家通过wsad移动下面的挡板,接住下落的弹球,弹击上头的球获得积分,弹球没接住则比赛结束,计算积分 三.项目模板结构 ...
- C语言Ⅰ博客作业02
1. 这个作业属于哪个课程 C语言程序设计Ⅰ 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-3/homework/8656 我在这个课程 ...
- [LeetCode] 211. 添加与搜索单词 - 数据结构设计
题目链接:https://leetcode-cn.com/problems/add-and-search-word-data-structure-design/ 题目描述: 设计一个支持以下两种操作的 ...
- [LeetCode] 210. 课程表 II
题目链接:https://leetcode-cn.com/problems/course-schedule-ii/ 题目描述: 现在你总共有 n 门课需要选,记为 0 到 n-1. 在选修某些课程之前 ...
- 介绍一下 except 的作用和用法?
except: #捕获所有异常 except: <异常名>: #捕获指定异常 except:<异常名 1, 异常名 2> : 捕获异常 1 或者异常 2 except:< ...
- java复习(4)异常
1.Java异常的分类和类结构图 1.Throwable是整个java异常体系的超类,所有的异常类都派生自这个类,包含Error和Exception这两个直接的子类,概括了所有能被当做异常跑出来的东西 ...
- 流畅的Python (Fluent Python) —— 前言
本书重点: 这本书并不是一本完备的 Python 使用手册,而是会强调 Python 作为编程语言独有的特性,这些特性或者是只有 Python 才具备的,或者是在其他大众语言里很少见的. Python ...