Android LowMemoryKiller原理分析

559 查看

一. 概述

Android的设计理念之一,便是应用程序退出,但进程还会继续存在系统以便再次启动时提高响应时间. 这样的设计会带来一个问题, 每个进程都有自己独立的内存地址空间,随着应用打开数量的增多,系统已使用的内存越来越大,就很有可能导致系统内存不足, 那么需要一个能管理所有进程,根据一定策略来释放进程的策略,这便有了lmk,全称为LowMemoryKiller(低内存杀手),lmkd来决定什么时间杀掉什么进程.

Android基于Linux的系统,其实Linux有类似的内存管理策略——OOM killer,全称(Out Of Memory Killer), OOM的策略更多的是用于分配内存不足时触发,将得分最高的进程杀掉。而lmk则会每隔一段时间检查一次,当系统剩余可用内存较低时,便会触发杀进程的策略,根据不同的剩余内存档位来来选择杀不同优先级的进程,而不是等到OOM时再来杀进程,真正OOM时系统可能已经处于异常状态,系统更希望的是未雨绸缪,在内存很低时来杀掉一些优先级较低的进程来保障后续操作的顺利进行。

二. framework层

位于ProcessList.java中定义了3种命令类型,这些文件的定义必须跟lmkd.c定义完全一致,格式分别如下:

功能 命令 对应方法 触发时机
更新oom_adj LMK_TARGET updateOomLevels AMS.updateConfiguration
设置进程adj LMK_PROCPRIO setOomAdj AMS.applyOomAdjLocked
移除进程 LMK_PROCREMOVE remove AMS.handleAppDiedLocked/cleanUpApplicationRecordLocked

在前面文章Android进程调度之adj算法中有讲到AMS.applyOomAdjLocked,接下来以这个过程为主线开始分析。

2.1 AMS.applyOomAdjLocked

2.2 PL.setOomAdj

buf大小为16个字节,依次写入LMK_PROCPRIO(命令类型), pid(进程pid), uid(进程uid), amt(目标adj),将这些字节通过socket发送给lmkd.

2.3 PL.writeLmkd