前言
系统运行一段时间之后,内存被逐渐分配出去,剩余的内存页越来越少,为了让系统能够继续运行,内核会适时启动page reclaim机制回收一部分内存,当回收的内存仍然不够内存分配时,便会触发OOM机制,选择性的kill掉系统中的某个进程,以瞬间回收大片的内存。内核的OOM在选择要被kill的进程时,优先选择占用内存较多、静态优先级较低的进程,但并不区分android应用中的前台程序和后台程序。从用户体验的角度来说,并不希望系统在内存不足时kill掉前台程序而被用户感知(如应用闪退等状况),而是希望首先kill掉后台程序。LMK(Low memory killer)就是这样一个用户层面的程序,用于在系统内存过低并达到OOM之前,按照用户定义的规则来kill进程。
根据以上描述,欲实现LMK,需要解决两个问题:
- OOM是内核在内存分配时,发现无法分配足够的内存触发的内核机制,LMK作为应用程序如何感知系统内存的紧缺?
- LMK在感知到内存压力时,如何选择合适的进程去kill,规则如何制定?
如何感知
采用PSI(Pressure Stall Information)评估系统资源压力,包括对CPU、Memory和IO三种系统资源的评估。当进程由于缺少某种资源而阻塞时,PSI技术捕捉这种状态变化,并统计进程处于阻塞状态的持续时间(即进程缺少资源的持续时间),根据该段持续时间在固定时间片段的时间占比衡量系统资源的紧缺程度。根据同一时间段,所有进程还是部分进程处于因缺少某一资源而导致的stuck状态,分别使用full和some指标对系统资源的紧缺程度进行衡量。
some是指一段时间内至少有一个task处于缺少某个资源而阻塞,而full则表示一段时间内所有task同时因为缺少某个相同的资源而被阻塞。以memory的some和full指标进行举例说明,在60s内task的运行情况如下所示:
其中,虚线部分表示task因为缺少memory而阻塞的时间,实线部分表示task的运行时间。假设当前系统中只有两个task,那么两个task虚线重合的部分即为系统处