本文主要基于android11,整理了android关于 oom killer, lowmemorykiller(lmk lmkd), kswapd的知识,还未深入去分析源码。
目录
oom_adj、oom_score、oom_score_adj三者的关系
android low memory killer(lmk)
linux oom
- 杀进程规则:按优先级,/proc/pid/oom_score(由oom_score_adj算出) 这个值越大,越容易被oom killer选中,
- linux oom 机制是做在kernel里边
- 为了避免自己的进程比较容易被杀,用户可以通过调低 oom_score_adj这个值。若直接 echo -17 > /proc/$PID/oom_adj,则可以让oom killer 忽略该进程。
- 具体实现机制在这oom_kill.c 。
- linux oom 是针对整个系统而言的,触发oom是在分配内存的时候(alloc_page(),分配内存肯定会走这个,内存都是按页管理),发现内存不足,触发oom killer,算出最应该杀的那些进程,杀了后回收内存(具体是杀一个还是杀好几个还没了解)。
oom_adj、oom_score、oom_score_adj三者的关系
- oom_score: kernel根据oom_score_adj值,结合该进程使用的内存量算出的值,后面无论是oom killer还是lmkd都是根据这个值来决定杀哪些进程的。
- oom_score_adj: 取值为-1000---1000,如果赋值为-1000将关闭oom killer对他的管理(如init、surfaceflinger等native 进程)。它和oom_adj都是kernel留给用户空间更改进程被杀优先级的接口,AMS调整app adj值就是通过把pid、uid、 adj 封装成 LMK_PROCPRIO 的消息包通过unix socket传给lmkd,通过lmkd改了这个值。
//frameworks/base/services/core/java/com/android/server/am/processlist.java
public static void setOomAdj(int pid, int uid, int amt) {
//...
ByteBuffer buf = ByteBuffer.allocate(4 * 4);
buf.putInt(LMK_PROCPRIO);