文章参考:http://gityuan.com/2017/08/12/proc_stat/

概述

CPU占用时间相关指标介绍:

cpu指标 含义
user 用户态时间
nice 用户态时间(低优先级,nice>0)
system 内核态时间
idle 空闲时间
iowait I/O等待时间
irq 硬中断
softirq 软中断

iowait时间是不可靠值,理由如下:

  • CPU不会等待I/O执行完成,而iowait是等待I/O完成的时间。 当CPU进入idle状态,很可能会调度另一个task执行,所以iowait计算时间偏小;
  • 多核CPU,iowait的计算并非某一个核,因此计算每一个cpu的iowait非常困难;

查看CPU

proc/stat

proc/stat节点记录的是系统进程整体的统计信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# CPU指标:user,nice, system, idle, iowait, irq, softirq
cpu 175233 89273 374099 21046665 21039 84630 34777 0 0 0
# 每个CPU核的指标信息
cpu0 51744 27274 98394 2481351 7461 40191 10615 0 0 0
cpu1 44616 26751 79604 2539837 5405 15390 9658 0 0 0
cpu2 26736 11355 92168 2565879 3389 12448 5299 0 0 0
cpu3 23854 11246 81751 2579368 2598 12812 7197 0 0 0
cpu4 6483 2416 5438 2722343 402 685 199 0 0 0
cpu5 4989 2833 3999 2725377 344 464 149 0 0 0
cpu6 9688 4492 7017 2712719 817 1568 774 0 0 0
cpu7 7119 2903 5725 2719788 620 1068 881 0 0 0
intr 31595836 0 0 0 0 7065789 0 607368 536357 3411 0 309 8351 0 0 0 0 61334 85229 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 43867 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 4 5 0 0 0 0 0 0 0 0 0 0 0 0 26369 3310 5115 533473 0 0 0 50704 14029 11 11 0 0 0 0 0 0 0 0 0 0 0 23 2066496 3126 8961 1560 87570 149 0 6 619 0 6 43655 201357 28872 0 0 0 0 0 21328 14671 174727 0 0 0 0 0 1382 0 4069 607491 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6 5 5 4 0 0 0 3193 0 1 0 2 0 2 0 2 2 0 0 2 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 186 0 0 0 4 0 12450 0 0 0 0 0 0 0 821 49 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 604 0 0 0 1060 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 70939 17045 0 0 52 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 905 684 0 0 44 0 0 0 0 8 16 0 0 0 0 0 0 0 0 2 2 0 2 4 391 8 0 0 0 0 0 0 0 0 368 0 1 0 0 0 52 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 175875 0 3 0 0 0 0 0 0 0 0 0 0 0 10 0 0 25447 0 4 1 0 1 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 12449 0 0
ctxt 42545958
btime 1628836036
processes 36442
procs_running 1
procs_blocked 0
softirq 10980749 17045 4056385 10323 191087 494350 0 2477778 2066245 0 1667536

时间单位,sysconf(_SC_CLK_TCK)一般地定义为jiffies(一般地等于10ms)

上述相关指标参数的说明:

cpu指标 含义
intr 系统启动以来的所有interrupts(硬中断)的次数情况
ctxt 系统上下文切换次数
btime 启动时长(单位:秒),从Epoch(即1970零时)开始到系统启动所经过的时长,每次启动会改变。此处的转换成北京时间:2021-08-13 14:27:16
processes 系统启动后所创建过的进程数量。当短时间该值特别大,系统可能出现异常
procs_running 处于Runnable状态的进程个数
procs_blocked 处于等待I/O完成的进程个数
softirq 软中断

另外:

1
2
3
crosshatch:/ $ cat /proc/uptime
89557.46 214652.60
crosshatch:/ $
  • 第一个值代表从开机到现在的累积时间(单位为秒), 开机后运行89557.46秒
  • 第二个值代表从开机到现在的CPU空闲时间,单位为秒.CPU空闲时间214652.60秒

结合btime获取当前的绝对时间,1500827856 + 82044 = 1500909900, 转换成北京时间2017/7/24 23:25:00,也就是当前执行命令cat /proc/uptime的时间点。

proc/<pid>/stat

proc/<pid>/stat用于获取某一个进程的统计信息,实现过程见fs/proc/array.c的do_task_stat()

1
2
3
crosshatch:/ $ cat /proc/30629/stat
# 进程ID 进程名 进程状态 父进程ID 父进程组ID
30629 (com.frewen.android.demo.debug) S 1004 1004 0 0 -1 1077952832 402812 1157592 3636 78 16811 6742 1919 3879 20 0 41 0 8691031 14519648256 26741 18446744073709551615 1 1 0 0 0 0 4612 1 1073775868 0 0 0 17 1 0 0 0 0 0 0 0 0 0 0 0 0 0

上述输出结果参数解析:

参数索引 参数 CPU指标 参数说明
1 30629 pid 进程ID
2 com.frewen.android.demo.debug comm task_struct结构体的进程名
3 S state 进程状态, 此处为S
4 1004 ppid 父进程ID (父进程是指通过fork方式,通过clone并非父进程)
5 1004 pgrp 进程组ID
6 0 session 进程会话组ID
7 0 tty_nr 当前进程的tty终点设备号
8 -1 tpgid 控制进程终端的前台进程号
9 1077952832 flags 进程标识位,定义在include/linux/sched.h中的PF_*, 此处等于1077952832
10 402812 minflt 次要缺页中断的次数,即无需从磁盘加载内存页. 比如COW和匿名页
11 1157592 cminflt 当前进程等待子进程的minflt
12 3636 majflt 主要缺页中断的次数,需要从磁盘加载内存页. 比如map文件
13 78 majflt 当前进程等待子进程的majflt
14 16811 utime 该进程处于用户态的时间,单位jiffies,此处等于16811
15 6742 cstime 该进程处于内核态的时间,单位jiffies,此处等于129684
16 1919 cutime 当前进程等待子进程的utime
17 3879 cstime 当前进程等待子进程的utime
18 20 priority 进程优先级, 此次等于10.
19 0 nice nice值,取值范围[19, -20],此处等于-10
20 41 num_threads 线程个数, 此处等于221
21 0 itrealvalue 该字段已废弃,恒等于0
22 8691031 starttime 自系统启动后的进程创建时间,单位jiffies
23 14519648256 vsize 进程的虚拟内存大小,单位为bytes
24 26741 rss 进程独占内存+共享库,单位pages,此处等于26741
25 18446744073709551615 rsslim rss大小上限

说明:

  • 第10~17行主要是随着时间而改变的量;
  • 内核时间单位,sysconf(_SC_CLK_TCK)一般地定义为jiffies(一般地等于10ms)

top指令

top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。下面详细介绍它的使用方法。top是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止该程序为止.比较准确的说,top命令提供了实时的对系统处理器的状态监视.它将显示系统中CPU最“敏感”的任务列表.该命令可以按CPU使用.内存使用和执行时间对任务进行排序;而且该命令的很多特性都可以通过交互式命令或者在个人定制文件中进行设定.

使用指令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
top [-]  [d]  [p]  [q]  [c]  [C]  [S]  [s]  [n]

1|crosshatch:/ $ top --help
usage: top [-Hbq] [-k FIELD,] [-o FIELD,] [-s SORT] [-n NUMBER] [-m LINES] [-d SECONDS] [-p PID,] [-u USER,]

Show process activity in real time.

-H Show threads
-k Fallback sort FIELDS (default -S,-%CPU,-ETIME,-PID)
-o Show FIELDS (def PID,USER,PR,NI,VIRT,RES,SHR,S,%CPU,%MEM,TIME+,CMDLINE)
-O Add FIELDS (replacing PR,NI,VIRT,RES,SHR,S from default)
-s Sort by field number (1-X, default 9)
-b Batch mode (no tty)
-d Delay SECONDS between each cycle (default 3)
-m Maximum number of tasks to show
-n Exit after NUMBER iterations
-p Show these PIDs
-u Show these USERs
-q Quiet (no header lines)

Cursor LEFT/RIGHT to change sort, UP/DOWN move list, space to force
update, R to reverse sort, Q to exit.

主要参数说明如下:

指令
top -m num Maximum number of processes to display. // 最多显示多少个进程
top -s col Column to sort by <cpu,vss,rss,thr> // 按哪列排序
top -t Show threads instead of processes. // 显示线程信息而不是进程
top -n num Updates to show before exiting. // 刷新次数
top -d 指定每两次屏幕信息刷新之间的时间间隔。当然用户可以使用s交互命令来改变之。
top -p 通过指定监控的进程ID来仅仅监控某个进程的状态。
top -q 该选项将使top没有任何延迟的进行刷新。如果调用程序有超级用户权限,那么top将以尽可能高的优先级运行。
top -S 指定累计模式。
top -s 使top命令在安全模式中运行。这将去除交互命令所带来的潜在危险。
top -i 使top不显示任何闲置或者僵死进程。
top -h Display this help screen. // 显示帮助文档

Android9.0之前的Top信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# top -m 5 -n 50 -d 10 // 最多显示5个进程的top信息。然后刷新50次

# User 用户进程CPU占用率 System 系统进程CPU占用率 IOW IO等待时间 IRQ 硬中断时间
User 34%, System 4%, IOW 0%, IRQ 0%
# CPU使用情况(指一个最小时间片内所占时间,单位jiffies。或者指所占进程数):
# User 处于用户态的运行时间,不包含优先值为负进程
# Nice 优先值为负的进程所占用的CPU时间
# Sys 处于核心态的运行时间
# Idle 除IO等待时间以外的其它等待时间
# IRQ 硬中断时间
# SIRQ 软中断时间
User 402 + Nice 0 + Sys 49 + Idle 710 + IOW 0 + IRQ 0 + SIRQ 0 = 1161

# PID 进程在系统中的ID
# CPU% 当前瞬时所以使用CPU占用率
# S 进程的状态,其中S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值是负数。
# #THR 程序当前所用的线程数
# VSS Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
# RSS Resident Set Size 实际使用物理内存(包含共享库占用的内存)
# PCY 调度策略优先级,SP_BACKGROUND/SP_FOREGROUND
# UID 运行当前进程的用户id
# Name 程序名称android.process.media
PID PR CPU% S #THR VSS RSS PCY UID Name
935 0 7% R 51 1771568K 78604K fg u0_a14 com.frewen.android.demo:asr
888 1 0% S 61 893784K 68812K fg u0_a14 com.frewen.android.demo:other
437 2 0% S 74 1432456K 66964K fg system system_server
804 3 0% S 81 919176K 61616K fg u0_a14 com.frewen.android.demo
174 3 0% S 6 1452304K 44104K fg root zygote
973 3 0% S 29 852524K 39568K fg u0_a14 com.frewen.android.demo:media

elapsedTime : 1



// 下面我们就来分析一下关于Top指令中,常用的一些指令分析:

adb shell top -m 20 -t -d 5 //按照线程信息打印占用前20的线程信息



Android9.0以后的Top信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# top -m 10 -n 3 -d 5 // 最多显示10个进程的top信息。然后刷新3次,每次间隔5秒


Tasks: 879 total, 1 running, 878 sleeping, 0 stopped, 0 zombie
Mem: 3665264K total, 3495092K used, 170172K free, 5246976 buffers
Swap: 2097148K total, 1091964K used, 1005184K free, 1741396K cached

# CPU使用情况(指一个最小时间片内所占时间,单位jiffies。或者指所占进程数):
# User 处于用户态的运行时间,不包含优先值为负进程
# Nice 优先值为负的进程所占用的CPU时间
# Sys 处于核心态的运行时间
# Idle 除IO等待时间以外的其它等待时间
# IRQ 硬中断时间
# SIRQ 软中断时间
# User 用户进程CPU占用率 用户进程CPU占用率(低优先级) System系统进程CPU占用率 IOW IO等待时间 IRQ 硬中断时间
800%cpu 7%user 0%nice 37%sys 750%idle 0%iow 3%irq 3%sirq 0%host

# PID 进程在系统中的ID
# CPU% 当前瞬时所以使用CPU占用率
# S 进程的状态,其中S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值是负数。
# #THR 程序当前所用的线程数
# VSS Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
# RSS Resident Set Size 实际使用物理内存(包含共享库占用的内存)
# PCY 调度策略优先级,SP_BACKGROUND/SP_FOREGROUND
# UID 运行当前进程的用户id
# Name 程序名称android.process.media
PID USER PR NI VIRT RES SHR S[%CPU] %MEM TIME+ ARGS
11526 shell 20 0 10G 3.0M 1.8M R 33.3 0.0 0:00.07 top -m 10 -n 3 -d 5
30629 u0_a285 20 0 14G 108M 61M S 10.0 3.0 6:54.15 cn.hikyson.android.godeye.sample.debug
710 system -3 -8 11G 14M 12M S 6.6 0.3 10:41.18 surfaceflinger
11120 root 20 0 0 0 0 S 3.3 0.0 0:00.12 [kworker/u16:1]
9382 u0_a206 20 0 14G 81M 38M S 3.3 2.2 3:29.48 io.bywave.nil:background
45 root 20 0 0 0 0 S 3.3 0.0 0:01.90 [rcuop/4]
11521 shell 20 0 10G 1.7M 1.1M S 0.0 0.0 0:00.01 sh
11489 root 20 0 0 0 0 S 0.0 0.0 0:00.06 [kworker/0:0]
11357 u0_a72 20 0 13G 51M 28M S 0.0 1.4 0:00.70 com.android.providers.calendar
11348 root 20 0 0 0 0 S 0.0 0.0 0:00.00 [kworker/4:0]