Android内存--Low-Memory-Killer

我们知道,当应用进入后台运行状态之后一段时间之后,应用进程会莫名其妙消失,最典型的例子就是闹钟类应用,第三方的闹钟应用很多都是不能及时响铃的,Why?

Low Memory Killer概览

原来是Android会定时检查并杀死一些进程,以释放内存,那么杀死的依据是什么?就是Low Memory Killer。

Low Memory Killer通过两个值来判定是否杀死这个进程:oom_adj和进程占用内存大小。

oom_adj

oom_adj对应表

名称 oom_adj 解释
FOREGROUD_APP 0 前台程序,可以理解为你正在使用的程序
VISIBLE_APP 1 用户可见的程序
SECONDARY_SERVER 2 后台服务,比如说QQ会在后台运行服务
HOME_APP 4 HOME,就是主界面
HIDDEN_APP 7 被隐藏的程序
CONTENT_PROVIDER 14 内容提供者
EMPTY_APP 15 空程序,既不提供服务,也不提供内容

这个表并不全,我们可以看RunningAppProcessInfo类,其中有个importance的值,这个值通过ActivityManagerService和这个表的值对应起来。
先获取手机的Root权限,打开你的Android手机Sys/Module/Lowmemorykiller/Parameters/Minfree的这个目录文件,阀值就被写在这里。以我手里这台Nexus7为例,我得到一串数字:5418,7224,14448,36120,45150,54180,这六个数字分别代表了6种进程(对应上文的顺序)可能被杀死的剩余内存最小阀值,这串数字的单位是Page,1Page=4Kb,我们做一下转换就54180Page=211Mb, 就是说当运行内存小于211Mb的时候,Lowmemory Killer就要杀死Empty App。Content Provider:45150Page=176Mb,当运行内存小于176Mb的时候,Lowmemory Killer不光要杀死Empty App,还要杀死Content Provider。Hidden App:141Mb,Secondary Server: 56Mb,Visible App:28Mb,Forgound App:21Mb,以此类推。http://www.jianshu.com/p/56c7cda86ad3

这个值越小,程序重要性越高。

Low Memory Killer 还维护一张表,定义了一组对应关系,当系统剩余内存位于内存临界值中的一个范围内时,如果一个进程的oom_adj值大于或等于这个临界值对应的oom_adj值就会被杀掉。如下:

oom_adj内存阀值表

并不是所有的手机都是这个对应值,在Linux层面,这个表是可以修改的。

oom_adj 内存警戒值(以4K为单位)
0 1536
1 2048
2 4096
7 5120
14 5632
15 6144

比如说,当可用内存小于6144 * 4K = 24MB时,开始杀所有的EMPTY_APP。

进程占用内存

一般来说,Android应用很难改变自己的进程重要级,但是我们可以控制自己的内存占用,同样重要的进程,内存越大越容易被杀死。

Killer的实现步骤

首先系统拿到自己剩余的内存大小,和oom_adj内存阀值表对照拿到min_adj,也就是应该被杀的进程adj值,然后遍历oom_adj表,拿到所有adj值比min_adj大的进程并比较每个进程的内存占用拿到 进程优先级较低(adj大)且占用内存高 的进程,然后发送信号把它Kill掉。

写完收工~

#【参考文献】