Android Kernel会定时执行一次检查,杀死一些进程以释放内存。那么如何判断哪些进程需要杀死呢?答案就是LowMemoryKiller机制。
LowMemoryKiller定时进行检查,主要是通过进程的oom_adj值来判定进程的重要性。这个值越小程序越重要,被杀死的可能性越低。
Android将应用的重要性分为以下几类:
名称 oom_adj 解释
FOREGROUND_APP 0 前台应用
VISIBLE_APP 1 可见应用
SECONDARY_SERVER 2 后台服务
HOME_APP 4 HOME,就是主界面
HIDDEN_APP 7 隐藏应用
CONTENT_PROVIDER 14 内容提供者
EMPTY_APP 15 空应用
另外,Android系统还维护着一张表,这张表是一个对应关系,如:
oom_adj 内存警戒值(以4K为单位)
0 1536
1 2048
2 4096
7 5120
14 5632
15 6144
每一个警戒值对应了一个重要性值,当系统的可用内存低于某个警戒值时,就会杀掉所有大于该警戒值所对应oom_adj值的应用。如:当可用内存小于5120 * 4K = 24MB时,开始杀所有的HIDDEN_APP、CONTENT_PROVIDER和EMPTY_APP。
oom_adj的取值范围是[-17, 15]。
根据pid获取oom_adj的值:
public class MainActivity extends Activity {
private static final int DEFAULT_OOM_ADJ = 16;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> runningAppProcesses = am
.getRunningAppProcesses();
for (RunningAppProcessInfo item : runningAppProcesses) {
int pid = item.pid;
int oom_adj = getProcessOomAdj(pid);
if (oom_adj != DEFAULT_OOM_ADJ) {
System.out.println("pkgName:" + item.pkgList[0] + ", adj:"
+ oom_adj);
}
}
}
private int getProcessOomAdj(int pid) {
int oom_adj = DEFAULT_OOM_ADJ;
File file = new File("proc/" + pid + "/oom_adj/");
BufferedReader br = null;
String s;
try {
br = new BufferedReader(new FileReader(file));
if ((s = br.readLine()) != null) {
oom_adj = Integer.valueOf(s);
}
} catch (Exception e) {
e.printStackTrace();
}
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return oom_adj;
}
}