Android中的Low Memory Killer
LinuxKernel中的OOM Killer,内核所管理的进程都有一个衡量其oom权重的值,存储在/proc/<PID>/oom_adj中。根据这一权重值以及各种因素,系统会实时给每个进程评分,以决定OOM时应该杀死哪些进程。比如oom_score分数越低的进程,被杀死的概率越小,或者说被杀死的时间越晚。
Android系统也为此开发了一个专门的驱动,名为Low Memory Killer(LMK)
源码:drivers/staging/android/Lowmemorykiller.c
Lowmemorykiller.c中定义了内存容量处于某层级时需要被处理的adj值,这个adj的取值范围是-17 ~ 15,数字越小表示进程级别越高
在LMK执行清理工作时,它需要知道当钱系统中所有进程的adj归属情况,也即系统如何给进程评定adj等级。
Android进程所属ADJ值
ADJ | 描述 |
HIDDEN_APP_MAX_AD=15 HIDDEN_APP_MIN_ADJ=9 |
当前只运行了不可见的Activity组件的进程 |
SERVICE_B_ADJ=8 | B list of service,和A list相比,它们对用户的粘合度要小一些 |
PREVIOUS_APP_ADJ=7 | 用户前一次交互的进程。按照用户的使用习惯,我们经常会在几个常用进程间切换,所以这类进程得到再次运行的概率比较大 |
HOME_APP_ADJ=6 | Launcher进程,它对用户的重要性不言而喻 |
SERVICE_ADJ=5 | 当前运行了application service的进 |
BACKUP_APP_ADJ=4 | 用于承载backup相关操作的进程 |
HEAVY_WEIGHT_APP_ADJ=3 | 重量级应用程序进程 |
PERCEPTIBLE_APP_ADJ=2 | 这类进程能被用户感觉到但不可见,如后台运行的音乐播放器 |
VISIBLE_APP_ADJ=1 | 有前台可见的Activity的进程,如果轻易杀死这类进程将严重影响用户的体验 |
FOREGROUND_APP_ADJ=0 | 当前正在前台运行的进程,也就是用户正在交互的那个进程 |
PERSISTENT_PROC_ADJ=-12 | Persistent性质的进程,如telephony |
SYSTEM_ADJ=-16 | 系统进程 |
方法一:写文件
进程的oom_adj可以通过写文件的形式来修改,路径为/proc/<PID>/oom_adj,比如init.rc中就有如下语句:
on early-init
write /proc/1/oom_adj-16
PID值为1的进程是init进程,这里将此进程的adj改为-16,以保证它不会被杀死。
方法二:android:persistent
对于某些非常重要的应用程序,我们不希望它们被系统杀死,一个最简单的方法就是在它的AndroidManifest.xml文件中给“application”标签添加“android:persistent=true”属性。