1、概述
LMK (low meminfo killer) 即当系统可用内存太低时,系统会触发LMK,杀掉一些进程释放内存出来。android 会为进程分配优先级,优先级越低的应用,在内存不足时,会优先被杀。优先级与进程的类型和进程被调度的次序有关系。
2、优先级
android 进程的优先级(从高到低)
前台进程,正在活动的Activity或者使用startForeground的Service。onReceive 的BroadcastReceiver 等 |
可见进程,如 onPause 的Activity |
服务进程,后台服务,如正在运行startService 启动的service |
后台进程,对用户交互无影响,如onStop状态的Activity 等 |
空进程,一般用作缓存以缩短下次启动时间 |
而LMK 则是根据oom_adj (Out of Memory Adjustment)来设置的,与android 的进程优先级有相似的地方,但又不完全相同
ADJ级别 | 取值 | 解释 |
---|---|---|
UNKNOWN_ADJ | 16 | 一般指将要会缓存进程,无法获取确定值 |
CACHED_APP_MAX_ADJ | 15 | 不可见进程的adj最大值 1 |
CACHED_APP_MIN_ADJ | 9 | 不可见进程的adj最小值 2 |
SERVICE_B_AD | 8 | B List中的Service(较老的、使用可能性更小) |
PREVIOUS_APP_ADJ | 7 | 上一个App的进程(往往通过按返回键) |
HOME_APP_ADJ | 6 | Home进程 |
SERVICE_ADJ | 5 | 服务进程(Service process) |
HEAVY_WEIGHT_APP_ADJ | 4 | 后台的重量级进程,system/rootdir/init.rc文件中设置 |
BACKUP_APP_ADJ | 3 | 备份进程 |
PERCEPTIBLE_APP_ADJ | 2 | 可感知进程,比如后台音乐播放 |
VISIBLE_APP_ADJ | 1 | 可见进程(Visible process) |
FOREGROUND_APP_ADJ | 0 | 前台进程(Foreground process) 6 |
PERSISTENT_SERVICE_ADJ | -11 | 关联着系统或persistent进程 |
PERSISTENT_PROC_ADJ | -12 | 系统persistent进程,比如telephony |
SYSTEM_ADJ | -16 | 系统进程 |
NATIVE_ADJ | -17 | native进程(不被系统管理) |
LMK根据当前可用内存情况来进行进程内存释放,总设计了6个级别,即上表中加粗的行,即LMK的杀进程的6档,如下:
- CACHED_APP_MAX_ADJ
- CACHED_APP_MIN_ADJ
- BACKUP_APP_ADJ
- PERCEPTIBLE_APP_ADJ
- VISIBLE_APP_ADJ
- FOREGROUND_APP_ADJ
当系统内存不足时,LMK也会从CACHED_APP_MAX_ADJ(第1档)开始杀进程,如果内存还不足,那么会杀CACHED_APP_MIN_ADJ(第2档),不断深入,以此类推。
3、adj
那么系统是怎么判断内存不足的呢?
系统根据这6档设置相对应的内存值,每个系统不一样,可以自定义
android 9 及以下
要注意的是,这里的单位不是KB,而是page(1 page = 4KB), 换算逻辑是(X / 1024 * 4)M
|
adj 显示出的不是上面16到-17 的取值,而是另一套更大范围的值。这样可以更进一步地细化进程的优先级,为每个进程排序。
LMK 机制会为每个应用的内存进行打分,当内存不足时,会将分高的应用先kill,所以oom_score_adj (下见 cat /proc/pid/oom_score_adj)就是另一种形式上的adj,比adj 更加细分。
android 10
getprop sys.lmk.minfree_levels
知道了当前阀值列表后,还需要查看当前应用对应的位置。
查看单个应用的优先级
|
以oom_score_adj 为准
查看当前系统应用优先级排列顺序
dumpsys activity o
dumpsys activity|grep -A 30 oom_adj (当前例子大概有20左右个进程排列,所以过滤显示30行,不是所有进程都会进入排列,dumpsys activity processes 也有相关信息,关键字 sorted by oom_adj)
也可以通过dumpsys meminfo 来查看排列,但是同一级内的优先级可能没有按顺序(实际测试时要注意)