在介绍updateOomAdjLocked方法之前,我们先补充一些进程相关的信息,便于后续更好的理解。
进程/轻量级进程状态
S:Suspended | 可中断的睡眠,可能是由于输出 Trace、GC 或 debug 被暂停 |
R:Running/Runnable | 运行或就绪状态 |
D:Disk Sleep | 不可中断的睡眠,通常是在等待 I/O,比如磁盘 I/O、网络 I/O 或者外设 I/O |
Z:Zombie | 退出状态,作为僵尸进程等待回收 |
X:Dead | 退出状态,即将被回收 |
T:Stopped/Tracing Stop | 暂停或跟踪状态 |
kTerminated | TERMINATED | TS_ZOMBIE | Thread.run has returned but Thread* still around |
kRunnable | RUNNABLE | TS_RUNNING | runnable |
kTimedWaiting | TIMED_WAITING | TS_WAIT | in Object.wait() with a timeout |
kSleeping | TIMED_WAITING | TS_SLEEPING | in Thread.sleep() |
kBlocked | BLOCKED | TS_MONITOR | blocked on a monitor |
kWaiting | WAITING | TS_WAIT | in Object.wait() with a timeout |
kWaitingForLockInflation | WAITING | TS_WAIT | blocked inflating a thin-lock |
kWaitingForTaskProcessor | WAITING | TS_WAIT | blocked waiting for taskProcessor |
kWaitingForGcToComplete | WAITING | TS_WAIT | blocked waiting for GC |
kWaitingForCheckPointsToRun | WAITING | TS_WAIT | GC waiting for checkpoints to run |
kWaitingPerformingGc | WAITING | TS_WAIT | performing GC |
kWaitingForDebuggerSend | WAITING | TS_WAIT | blocked waiting for events to be sent |
kWaitingForDebuggerToAttach | WAITING | TS_WAIT | blocked waiting for debugger to attach |
kWaitingInMainDebuggerLoop | WAITING | TS_WAIT | blocking/reading/processing debugger events |
kWaitingForDebuggerSuspension | WAITING | TS_WAIT | waiting for debugger suspend all |
kWaitingForJniOnLoad | WAITING | TS_WAIT | waiting for execution of dlopen and JNI on load code |
kWaitingForSignalCatcherOutput | WAITING | TS_WAIT | waiting for signal catcher IO to complete |
kWaitingInMainSignalCatcherLoop | WAITING | TS_WAIT | blocking/reading/processing signals |
kWaitingForDeoptimization | WAITING | TS_WAIT | waiting for deoptimization suspend all |
kWaitingForMethodTracingStart | WAITING | TS_WAIT | waiting for method tracing to start |
kWaitingForVisitObjects | WAITING | TS_WAIT | waiting for visiting objects |
kWaitingForGetObjectsAllocated | WAITING | TS_WAIT | waiting for getting the number of allocated objects |
kWaitingWeakGcRootRead | WAITING | TS_WAIT | waiting on the GC to read a weak root |
kWaitingForGcThreadFlip | WAITING | TS_WAIT | waiting on the GC thread flip (CC collector) to finish |
kStarting | NEW | TS_WAIT | native thread started not yet ready to run managed code |
kNative | RUNNABLE | TS_RUNNING | running in a JNI native method |
kSuspended | RUNNABLE | TS_RUNNING | suspended by GC or debugger |
adb shell cat /proc/stat信息解读
cpu | 175450 | 770389 | 104310 | 536443 | 3566329 | 8709 | 102422 | 36164 | 0 | 0 |
cpu0 | 172851 | 34125 | 127623 | 1411853 | 6149 | 27805 | 9041 | 0 | 0 | 0 |
cpu1 | 147579 | 33401 | 126758 | 272340 | 876 | 29391 | 6374 | 0 | 0 | 0 |
cpu2 | 111014 | 10281 | 115137 | 285843 | 432 | 20357 | 6809 | 0 | 0 | 0 |
cpu3 | 29311 | 1895 | 85313 | 298551 | 349 | 18759 | 12336 | 0 | 0 | 0 |
cpu4 | 37001 | 4881 | 15848 | 328430 | 132 | 998 | 367 | 0 | 0 | 0 |
cpu5 | 44830 | 6948 | 21162 | 328251 | 170 | 1406 | 398 | 0 | 0 | 0 |
cpu6 | 52353 | 5834 | 20824 | 319511 | 327 | 1642 | 391 | 0 | 0 | 0 |
cpu7 | 60241714 | 6945 | 23778 | 321550 | 274 | 2064 | 448 | 0 | 0 | 0 |
intr | 93194940 | 0 | 0 | 0 | 0 | 16362540 | 0 | 1445523 | 1041656 | 10753 |
ctxt | 1535500109 | |||||||||
btime | 77945 | |||||||||
processes | 1 | |||||||||
procs_running | 0 | |||||||||
procs_blocked | 12604019 | |||||||||
softirq | 427072 | 3138437 | 13792 | 312241 | 1115826 | 0 | 3088155 | 2292488 | 0 |
我们通过adb shell cat /proc/stat获取的是从系统启动开始累积到当前时刻的CPU活动信息,cpu信息以第一行为例,他们分别表示的意思如下
175450:从系统启动开始累计到当前时刻,用户态的CPU时间(单位:jiffies) ,不包含 nice值为负进程。1jiffies=0.01秒
770389:从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间(单位:jiffies)
104310:从系统启动开始累计到当前时刻,核心时间(单位:jiffies)
536443:从系统启动开始累计到当前时刻,除硬盘IO等待时间以外其它等待时间(单位:jiffies)
3566329:从系统启动开始累计到当前时刻,硬盘IO等待时间(单位:jiffies)
8709:从系统启动开始累计到当前时刻,硬中断时间(单位:jiffies)
102422:从系统启动开始累计到当前时刻,软中断时间(单位:jiffies)
纵向其他信息分别代表的意思如下
intr:这行给出中断的信息,第一个为自系统启动以来,发生的所有的中断的次数;然后每个数对应一个特定的中断自系统启动以来所发生的次数。
ctxt:自系统启动以来CPU发生的上下文交换的次
btime:给出了从系统启动到现在为止的时间,单位为秒
processes:自系统启动以来所创建的任务的个数目(total_forks)
procs_running:当前运行队列的任务的数目
procs_blocked:当前被阻塞的任务的数目
adb shell cat /proc/***/stat信息解读
以测试手机1339进程为例:
pid | 进程包括轻量级进程及线程号 | 1339 |
comm | 应用程序或命令的名字 | (system_server) |
task_state | 任务状态 | S |
ppid | 父进程ID | 637 |
pgid | 线程组号 | 637 |
sid | 该任务所在的会话组ID | 0 |
tty_nr | 该任务的tty终端的设备号,INT(34817/256)=主设备号,(34817-主设备号)=次设备号 | 0 |
tty_pgrp | 终端的进程组号,当前运行在该任务所在终端的前台任务(包括shell 应用程序)的PID | -1 |
task→flags | 进程标志位,查看该任务的特性 | 1077936448 |
min_flt | 该任务不需要从硬盘拷数据而发生的缺页(次缺页)的次数 | 979752 |
cmin_flt | 累计的该任务的所有的waited-for进程曾经发生的次缺页的次数目 | 3291 |
maj_flt | 该任务需要从硬盘拷数据而发生的缺页(主缺页)的次数 | 1546 |
cmaj_flt | 累计的该任务的所有的waited-for进程曾经发生的主缺页的次数目 | 2 |
utime | 该任务在用户态运行的时间,单位为jiffies | 30282 |
stime | 该任务在核心态运行的时间,单位为jiffies | 26395 |
cutime | 累计的该任务的所有的waited-for进程曾经在用户态运行的时间,单位为jiffies | 10 |
cstime | 累计的该任务的所有的waited-for进程曾经在核心态运行的时间,单位为jiffies | 4 |
priority | 任务的动态优先级 | 18 |
nice | 任务的静态优先级 | -2 |
num_threads | 该任务所在的线程组里线程的个数 | 145 |
it_real_value | 由于计时间隔导致的下一个 SIGALRM 发送进程的时延,以 jiffy 为单位 | 0 |
start_time | 该任务启动的时间,单位为jiffies | 5069 |
vsize | 该任务的虚拟地址空间大小 | 4864786432 |
rss | 该任务当前驻留物理地址空间的大小 | 79719 |
rlim | 该任务能驻留物理地址空间的最大值 | 1.84467440737096E+019 |
start_code | 该任务在虚拟地址空间的代码段的起始地址 | 1 |
end_code | 该任务在虚拟地址空间的代码段的结束地址 | 1 |
start_stack | 该任务在虚拟地址空间的栈的结束地址 | 0 |
kstkesp | esp(32 位堆栈指针) 的当前值, 与在进程的内核堆栈页得到的一致 | 0 |
kstkeip | 指向将要执行的指令的指针, EIP(32 位指令指针)的当前值 | 0 |
pendingsig | 待处理信号的位图,记录发送给进程的普通信号 | 0 |
block_sig | 阻塞信号的位图 | 4612 |
sigign | 忽略的信号的位图 | 1 |
sigcatch | 被俘获的信号的位图 | 1073775864 |
wchan | 如果该进程是睡眠状态,该值给出调度的调用点 | 0 |
nswap | 被swapped的页数,当前没用 | 0 |
cnswap | 所有子进程被swapped的页数的和,当前没用 | 0 |
exit_signal | 该进程结束时,向父进程所发送的信号 | 17 |
ask_cpu(task) | 运行在哪个CPU上 | 0 |
task_rt_priority | 实时进程的相对优先级别 | 0 |
task_policy | 进程的调度策略,0=非实时进程,1=FIFO实时进程;2=RR实时进程 | 0 |
进程ADJ值
SYSTEM_ADJ | -900 | 系统进程 |
PERSISTENT_PROC_ADJ | -800 | 系统persistent进程 |
PERSISTENT_SERVICE_ADJ | -700 | 关联着系统或persistent进程 |
FOREGROUND_APP_ADJ | 0 | 前台进程 |
VISIBLE_APP_ADJ | 100 | 可见进程 |
PERCEPTIBLE_APP_ADJ | 200 | 可感知的进程 |
BACKUP_APP_ADJ | 300 | 备份进程 |
HEAVY_WEIGHT_APP_ADJ | 400 | 重量级进程 |
SERVICE_ADJ | 500 | 服务进程 |
HOME_APP_ADJ | 600 | Home进程 |
PREVIOUS_APP_ADJ | 700 | 前一个App进程 |
SERVICE_B_ADJ | 800 | B集合中的进程 |
CACHED_APP_MIN_ADJ | 900 | 缓存进程的最小值 |
CACHED_APP_MAX_ADJ | 906 | 缓存进程的最大值 |
进程的状态描述
PROCESS_STATE_UNKNOWN | -1 | |
PROCESS_STATE_PERSISTENT | 0 | 系统persistent进程 |
PROCESS_STATE_PERSISTENT_UI | 1 | 系统persistent进程,正在进行UI相关的操作 |
PROCESS_STATE_TOP | 2 | 涵盖了用户可见活动的进程 |
PROCESS_STATE_FOREGROUND_SERVICE | 3 | 托管前台服务的进程 |
PROCESS_STATE_BOUND_FOREGROUND_SERVICE | 4 | 通过bind的形式托管前台服务的进程 |
PROCESS_STATE_IMPORTANT_FOREGROUND | 5 | 对于用户比较重要的前台进程 |
PROCESS_STATE_IMPORTANT_BACKGROUND | 6 | 对于用户比较重要的后台进程 |
PROCESS_STATE_TRANSIENT_BACKGROUND | 7 | 短暂的后台进程 |
PROCESS_STATE_BACKUP | 8 | 备份进程 |
PROCESS_STATE_SERVICE | 9 | 服务进程 |
PROCESS_STATE_RECEIVER | 10 | 广播进程 |
PROCESS_STATE_TOP_SLEEPING | 11 | 和PROCESS_STATE_TOP一样,但是区别是手机处于sleeping状态 |
PROCESS_STATE_HEAVY_WEIGHT | 12 | 重量级进程 |
PROCESS_STATE_HOME | 13 | Home进程 |
PROCESS_STATE_LAST_ACTIVITY | 14 | 后台进程,但是托管了用户最后运行的Activity |
PROCESS_STATE_CACHED_ACTIVITY | 15 | 后台托管有Activity的进程 |
PROCESS_STATE_CACHED_ACTIVITY_CLIENT | 16 | 托管存在客户端的Activity的进程 |
PROCESS_STATE_CACHED_RECENT | 17 | 与recent中关联的缓存进程 |
PROCESS_STATE_CACHED_EMPTY | 18 | 空进程 |
PROCESS_STATE_NONEXISTENT | 19 | 不存在的进程 |
进程的内存
Item | 全称 | 含义 | 等价 |
USS | Unique Set Size | 物理内存 | 进程独占的内存 |
PSS | Proportional Set Size | 物理内存 | PSS= USS+ 按比例包含共享库 |
RSS | Resident Set Size | 物理内存 | RSS= USS+ 包含共享库 |
VSS | Virtual Set Size | 虚拟内存 | VSS= RSS+ 未分配实际物理内存 |
参考文章:
https://blog.csdn.net/cybertan/article/details/7596633
https://my.oschina.net/u/262208/blog/378660