1 2 3 |
frameworks/base/services/core/java/com/android/server/am/ProcessList.java platform/system/core/lmkd/lmkd.c kernel/common/drivers/staging/Android/lowmemorykiller.c |
一. 概述
Android的设计理念之一,便是应用程序退出,但进程还会继续存在系统以便再次启动时提高响应时间. 这样的设计会带来一个问题, 每个进程都有自己独立的内存地址空间,随着应用打开数量的增多,系统已使用的内存越来越大,就很有可能导致系统内存不足, 那么需要一个能管理所有进程,根据一定策略来释放进程的策略,这便有了lmk
,全称为LowMemoryKiller(低内存杀手),lmkd来决定什么时间杀掉什么进程.
Android基于Linux的系统,其实Linux有类似的内存管理策略——OOM killer,全称(Out Of Memory Killer), OOM的策略更多的是用于分配内存不足时触发,将得分最高的进程杀掉。而lmk
则会每隔一段时间检查一次,当系统剩余可用内存较低时,便会触发杀进程的策略,根据不同的剩余内存档位来来选择杀不同优先级的进程,而不是等到OOM时再来杀进程,真正OOM时系统可能已经处于异常状态,系统更希望的是未雨绸缪,在内存很低时来杀掉一些优先级较低的进程来保障后续操作的顺利进行。
二. framework层
位于ProcessList.java
中定义了3种命令类型,这些文件的定义必须跟lmkd.c
定义完全一致,格式分别如下:
1 2 3 |
LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs) LMK_PROCPRIO <pid> <prio> LMK_PROCREMOVE <pid> |
功能 | 命令 | 对应方法 | 触发时机 |
---|---|---|---|
更新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
1 2 3 4 5 6 7 8 9 10 |
private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now, long nowElapsed) { ... if (app.curAdj != app.setAdj) { //【见小节2.2】 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); app.setAdj = app.curAdj; } ... } |
2.2 PL.setOomAdj
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public static final void setOomAdj(int pid, int uid, int amt) { //当adj=16,则直接返回 if (amt == UNKNOWN_ADJ) return; long start = SystemClock.elapsedRealtime(); ByteBuffer buf = ByteBuffer.allocate(4 * 4); buf.putInt(LMK_PROCPRIO); buf.putInt(pid); buf.putInt(uid); buf.putInt(amt); //将16Byte字节写入socket【见小节2.3】 writeLmkd(buf); long now = SystemClock.elapsedRealtime(); if ((now-start) > 250) { Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid + " = " + amt); } } |
buf大小为16个字节,依次写入LMK_PROCPRIO(命令类型), pid(进程pid), uid(进程uid), amt(目标adj),将这些字节通过socket发送给lmkd.
2.3 PL.writeLmkd
1 2 3 4 5 6 7 8 9 a-settings=" minimize scroll-always" style=" margin-top: 12px; margin-bottom: 12px; font-size: 13px !important; line-height: 15px !important;">
一. 概述Android的设计理念之一,便是应用程序退出,但进程还会继续存在系统以便再次启动时提高响应时间. 这样的设计会带来一个问题, 每个进程都有自己独立的内存地址空间,随着应用打开数量的增多,系统已使用的内存越来越大,就很有可能导致系统内存不足, 那么需要一个能管理所有进程,根据一定策略来释放进程的策略,这便有了 Android基于Linux的系统,其实Linux有类似的内存管理策略——OOM killer,全称(Out Of Memory Killer), OOM的策略更多的是用于分配内存不足时触发,将得分最高的进程杀掉。而 二. framework层位于
在前面文章Android进程调度之adj算法中有讲到 2.1 AMS.applyOomAdjLocked
2.2 PL.setOomAdj
buf大小为16个字节,依次写入LMK_PROCPRIO(命令类型), pid(进程pid), uid(进程uid), amt(目标adj),将这些字节通过socket发送给lmkd. 2.3 PL.writeLmkd
|