安卓应用不用太在意内存回收,首先android上的应用是带有独立java虚拟机的,也就是每开一个应用就会打开一个独立的虚拟机,虚拟机有自己的一套规则回收内存;同时和java的垃圾回收机制类似,android系统有一个规则来主动回收内存。进行内存回收有个阀值,只有低于这个值系统才会按一个列表来关闭用户不需要的东西。
下面介绍android内核的低内存管理,由于上述的这个阈值存在,所以我们会看到android内存使用比例并不高。事实上高剩余内存并不影响速度,相反加快了下次启动应用的速度。这本来就是 android标榜的优势之一,如果人为去关闭进程,没有太大必要,用户体验也不好。比Linux的标准的OOM(Out Of Memory)机制更加灵活,它可以根据需要杀死进程以释放需要的内存 。源代码 位 于 drivers/staging/android/lowmemorykiller.c。
Linux使用OOM(Out Of Memory,内存不足)的机制来完成这个任务,该机制会在系统内存不足的情况下,选择一个进程并将其 Kill 掉。Android则使用了一个新的机制——Low Memory Killer 来完成同样的任务。下面首先来看看 Low MemoryKiller 机制的原理以及它是如何选择将被 Kill 的进程的。
1.Low Memory Killer 的原理和机制
Low Memory Killer 在用户空间中指定了一组内存临界值,当其中的某个值与进程描述中的oom_adj值在同一范围时,该进程将被Kill掉。在“/sys/module/lowmemorykiller/parameters/adj”中指定oom_adj的最小值,在“/sys/module/lowmemorykiller/parameters/minfree” 中指定空闲页面的数量,所有的值都用一个逗号将其隔开且以升序排列。比如:把“0,8”写入到/sys/module/lowmemorykiller/parameters/adj中,把“1024,4096”写入到/sys/module/lowmemory-killer/parameters/minfree 中,就表示当一个进程的空闲存储空间下降到 4096 个页面时,oom_adj 值为 8 或者更大的进程会被 Kill 掉。同理,当一个进程发现空闲存储空间下降到 1024 个页面时, oom_adj 值为 0 或者更大的进程会被 Kill 掉。在 lowmemorykiller.c 中就指定了这样的默认值,如下所示:
static int lowmem_adj[6] = {
0,
1,
6,
12,
};
static int lowmem_adj_size = 4;
static size_t lowmem_minfree[6] = {
3*512, // 单位页,6MB
2*1024, // 8MB
4*1024, // 16MB
16*1024, // 64MB
};
static int lowmem_minfree_size = 4;
这就说明,当一个进程的空闲空间下降到 3*512 个页面时,oom_adj 值为 0 或者更大的进 程会被 Kill 掉;当一个进程的空闲空间下降到 2*1024 个页面时,oom_adj 值为 10 或者更大的进程会被 Kill 掉,依此类推。
进程的oom_adj值是由上层决定的,Android将进程分为6个等级,分别对应不同的lowmem_adj,它们按优先级顺序由高到低依次是:
1前台进程(foreground)
目前正在屏幕上显示的进程和一些系统进程。举例来说,Dialer,Storage,Google Search等系统进程就是前台进程;再举例来说,当你运行一个程序,如浏览器,当浏览器界面在前台显示时,浏览器属于前台进程(foreground),但一旦你按home回到主界面,浏览器就变成了后台程序(background)。我们最不希望终止的进程就是前台进程。
2可见进程(visible)
可见进程是一些不再前台,但用户依然可见的进程,举个例来说:widget、输入法等,都属于visible。这部分进程虽然不在前台,但与我们的使用也密切相关,我们也不希望它们被终止(还比如时钟、天气,新闻等widget用户肯定不希望被终止,那它们将无法同步,你也不希望输入法被终止,否则你每次输入时都需要重新启动输入法)。
3桌面进程(home app)
即launcher(桌面启动器),保证在多任务切换之后,可以快速返回到home界面而不需重新加载launcher。
4次要服务(secondary server)
目前正在运行的一些服务