基于 Linux 内核 OOMKiller 的核心思想,Android 系统拓展出了自己的内存监控体系,相比 Linux 达到临界值才触发,Android 实现了不同梯级的 Killer。Android 系统为此开发了专门的驱动,名为 Low Memory Killer,源码在内核的 /drivers/staging/android/Lowmemorykiller.c 中。
Lowmemorykiller.c 中有如下定义:
static int lowmem_adj[6] = {0, 1, 6, 12};
static int lowmem_adj_size = 4; //页大小
static size_t lowmem_minfree[6] = { //元素使用时以 lowmem_adj_size 为单位
3 * 512, //6MB
2 * 1024, //8MB
4 * 1024, //16MB
16 * 1024,//64MB
};
lowmem_minfree 定义了可用内存容量对应的不同梯级。lowmem_adj 与 lowmem_minfree 中的梯级一一对应,表示处于某梯级时需要被处理的 adj 值。adj 值用来描述进程的优先级,取值范围为 -17~15,数字越小表示进程优先级越高,被杀死的概率越小。
比如当可用内存低于 64MB 时,即 lowmem_minfree 第 4 梯级,对应于 lowmem_adj 的 12,那就会清理掉优先级低于 12(即 adj>12)的进程。
上面这两个数组中梯级的定义只是系统的预定义值,Android 系统还提供了相应的文件供我们修改这两组值,路径为:
/sys/module/lowmemorykiller/parameters/adj
/sys/module/lowmemorykil
ler/parameters/minfree
可以在 init.rc(系统启动时由 init 进程解析的一个脚本) 中,这样修改:
write /sys/module/lowmemorykiller/parameters/adj 0, 8
write /sys/module/lowmemorykiller/parameters/minfree 1024, 4096
另外 ActivityManagerService 中有一个 updateOomLevels 方法也是通过修改这两个文件来实现的,AMS 在运行时会根据当前的系统配置自动调整 adj 和 minfree,以尽可能适配不同的硬件设备。
了解了 Low Memory Killer 的梯级规则后,来看下 Android 进程的 adj 值含义:
除了表格中系统的评定标准,有没有办法改变某一进程的 adj 值呢?和修改上面的 adj、minfree 梯级类似,进程的 adj 值也可以通过写文件的方式来修改,路径为 /proc/{PID}/oom_adj,比如 init.rc 中:
write /proc/1/oom_adj -16
另外还可以在 AndroidManifest.x