哎,看到两篇文章,一篇很好看懂,一篇讲得让人很堵。
好的列前面:
http://blog.sina.com.cn/s/blog_4d66a3cb0100prfe.html
合理配置这张表,对于小内存设备有非常重要的作用。
Lowmeme_adj中各项数值代表阈值的警戒级数,lowmem_minfree代表对应级数的剩余内存。
也就是说,当系统的剩余内存为小于6MB时候,警戒级数为0,当系统内存剩余小于8M而大于
6M的时候,警戒级数为1,当内存小于64M大于16MB的时候,警戒级数为12.
Low memory killer 的规则就是根据当前系统的剩余内存多少来获取当前的警戒级数,如果进程的oom_adj大于警戒级数并且最大,进程将会被杀死(相同omm_adj的,则杀死占用内存较多的)。Omm_adj越小,代表进程越重要。一些前台的进程,oom_adj会比较小,而后台的服务,omm_adj会比较大,所以当内存不足的时候,Low memory killer 杀掉的必然先杀掉的是后台服务而不是前台的进程。
OK,现在我们来看具体代码,也就是lowmem_shrink这个回调函数:
首先通过global_page_state获取当前剩余内存大小,然后根据剩余内存和内存阈值表查找当前的内存警戒数min_adj。接着遍历所有进程,找到oom_adj大于min_adj并且oom_adj最大的进程:
进程的oom_adj 小于警戒阈值,则无视。
获取这个进程所占用的内存大小tasksize,如果小于比我们当前选出进程的内存,则无视。
如果大于则选中这个进程:
经过for_each的遍历,selected 就是我们选出要释放掉的bad进程,它具有下面两个条件:
Oom_adj大于当前警戒阈值并且最大。
在同样大小的oom_adj中,占用内存最多。
最后,我们释放掉这个进程的内存,通过force_sig(SIGKILL, selected)来向进程发送一个不可以忽略或阻塞的SIGKILL信号。
阈值表可以通过/sys/module/lowmemorykiller/parameters/adj和
/sys/module/lowmemorykiller/parameters/minfree进行配置,例如在init.rc中:
# Write value must be consistent with the above properties.
write /sys/module/lowmemorykiller/parameters/adj 0,1,2,7,14,15
write /proc/sys/vm/overcommit_memory 1
write /sys/module/lowmemorykiller/parameters/minfree 1536,2048,4096,5120,5632,6144
class_start default
进程oom_adj同样可以进行设置,通过write /proc/<PID>/oom_adj
# Set init its forked children's oom_adj.
write /proc/1/oom_adj -16
ActivityManagerService定义各种进程的oom_adj, CORE_SERVER_ADJ代表一些核心的服务的omm_adj, 数值为-12,由前面的分析可知道,这类进程永远也不会被杀死。
其他未赋值的都在static块中进行了初始化,是通过system/rootdir/init.rc进行配置的:
# Define the oom_adj values for the classes of processes that can be
# killed by the kernel.
# Define the memory thresholds at which the above process classes will
# be killed.
=======================================================================
Low Memory Killer(低内存管理)
对于PC来说,内存是至关重要。如果某个程序发生了内存泄漏,那么一般情况下系统就会将其进程Kill掉。Linux中使用一种名称为OOM(Out Of Memory,内存不足)的机制来完成这个任务,该机制会在系统内存不足的情况下,选择一个进程并将其Kill掉。Android则使用了一个新的机制——Low Memory Killer来完成同样的任务。下面首先来看看Low Memory Killer机制的原理以及它是如何选择将被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中就指定了这样的值,如下所示: