加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

Android Low Memory Killer详解

发布时间:2021-11-25 17:18:52 所属栏目:PHP教程 来源:互联网
导读:基本原理: Android的Low Memory Killer是在标准linux kernel的OOM基础上修改而来的一种内存管理机制,当系统内存不足时,杀死Bad进程释放其内存。Bad进程的选择标准有两个:oom_adj和占用内存的大

基本原理:
 
Android的Low Memory Killer是在标准linux kernel的OOM基础上修改而来的一种内存管理机制,当系统内存不足时,杀死Bad进程释放其内存。Bad进程的选择标准有两个:oom_adj和占用内存的大小。oom_adj代表进程的优先级,数值越大,优先级越高,对应每个oom_adj都有一个空闲内存的阈值。Android Kernel每隔一段时间会检查当前空闲内存是否低于某个阈值,如果是,则杀死oom_adj最大的Bad进程,如果有两个以上Bad进程oom_adj相同,则杀死其中占用内存最多的进程。  
 
Low Memory Killer与OOM的区别
 
OOM即Out of Memory是标准linux Kernel的一种内存管理机制,Low Memory Killer在它基础上作了改进:
 
OOM基于多个标准给每个进程打分,分最高的进程将被杀死;Low MemoryKiller则用oom_adj和占用内存的大小来选择Bad进程,OOM在内存分配不足时调用,而Low Memory Killer每隔一段时间就会检查,一旦发现空闲内存低于某个阈值,则杀死Bad进程。
 
Low Memory Killer的实现
 
Low Memory Killer的源代码在drivers/staging/android/lowmemorykiller.c中,它是通过注册Cache Shrinker来实现的。Cache Shrinker是标准linux kernel回收内存页面的一种机制,它由内核线程kswapd监控,当空闲内存页面不足时,kswapd会调用注册的Shrinker回调函数,来回收内存页面。
 
Low Memory Killer是在模块初始化时注册Cache Shrinker的,代码如下:
 
static int__init lowmem_init(void)
 
{
 
register_shrinker(&lowmem_shrinker);//注册Cache Shrinker
 
return 0;
 
}
 
lowmem_shrinker的定义如下:
 
static struct shrinker lowmem_shrinker=
 
{
 
.shrink=lowmem_shrink,
 
.seeks=DEFAULT_SEEKS*16
 
};
 
register_shrinker会将lowmem_shrink加入Shrinker List中,被kswapd在遍历Shrinker List时调用,而Low Memory Killer的功能就是在lowmem_shrink中实现的。
 
lowmem_shrink用两个数组作为选择Bad进程的依据,这两个数组的定义如下:
 
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
 
};
 
lowmem_minfree保存空闲内存的阈值,单位是一个页面4K,lowmem_adj保存每个阈值对应的优先级。lowmem_shrink首先计算当前空闲内存的大小,如果小于某个阈值,则以该阈值对应的优先级为基准,遍历各个进程,计算每个进程占用内存的大小,找出优先级大于基准优先级的进程,在这些进程中选择优先级最大的杀死,如果优先级相同,则选择占用内存最多的进程。
 
lowmem_shrink杀死进程的方法是向进程发送一个不可以忽略或阻塞的SIGKILL信号:
 
force_sig(SIGKILL,selected);
 
 
 
用户接口
 
设置空闲内存阈值的接口:/sys/module/lowmemorykiller/parameters/minfree,设置对应优先级的接口:/sys/module/lowmemorykiller/parameters/adj,设置各个进程优先级的接口:/proc/<进程pid>/oom_adj。
 
Android启动时读取的配置文件/init.rc中定义了相应的属性供AP使用并有设置这些参数:
 
#killed by the kernel.These are used in
 
ActivityManagerService.
 
setprop ro.FOREGROUND_APP_ADJ 0
 
setprop ro.VISIBLE_APP_ADJ 1
 
setprop ro.SECONDARY_SERVER_ADJ 2
 
setprop ro.BACKUP_APP_ADJ 2
 
setprop ro.HOME_APP_ADJ 4
 
setprop ro.HIDDEN_APP_MIN_ADJ 7
 
setprop ro.CONTENT_PROVIDER_ADJ 14
 
setprop ro.EMPTY_APP_ADJ 15
 
#Define the memory thresholds at which the above process
 
classes will
 
#be killed.These numbers are in pages(4k).
 
setprop ro.FOREGROUND_APP_MEM 1536
 
setprop ro.VISIBLE_APP_MEM 2048
 
setprop ro.SECONDARY_SERVER_MEM 4096
 
setprop ro.BACKUP_APP_MEM 4096
 
setprop ro.HOME_APP_MEM 4096
 
setprop ro.HIDDEN_APP_MEM 5120
 
setprop ro.CONTENT_PROVIDER_MEM 5632
 
setprop ro.EMPTY_APP_MEM 6144
 
#Write value must be consistent with the above properties.
 
#Note that the driver only supports 6 slots,so we have HOME_APP
 
at the
 
#same memory level as services.
 
write/sys/module/lowmemorykiller/parameters/adj
 
0,1,2,7,14,15
 
write/sys/module/lowmemorykiller/parameters/minfree
 
1536,2048,4096,5120,5632,6144
 
#Set init its forked children's oom_adj.
 
write/proc/1/oom_adj-16
 
从以上设置可以看出,将init进程oom_adj设置为-16,从而保证init进程永远不会被杀掉

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读