Cgroup-memory子系统分析(2)

1.1      Oom

1.1.1      简介

Oom的全称是out-of-memory,是内核在处理系统内存不足而又回收无果的情况下采取的一种措施,内核会经过选择杀死一些进程,以释放一些内存,满足当前内存申请的需求。所以oom是一种系统行为,对应到memcg的oom,其原理和动机跟全局oom是一样的,区别只在于对象的不同,全局oom的对象是整个系统中所有进程,而memcg oom只针对memcg中的进程(如果使能了hierarchy,还包括所有子memcg中的进程),这里的对象主要是指oom时内核选择从哪些进程中杀死一些进程,所以memcg的oom只可能杀死属于该memcg的进程。

1.1.2      实现

跟全局oom一样,memcg的oom也分成select_bad_process和oom_kill_process两个过程:

a.     select_bad_process找出该memcg下最该被kill的进程(如果memcg设置了hierarchy,也会考虑子memcg下的进程);

b.    oom_kill_process杀掉选中的进程及与其共用mm的进程(杀进程的目的是释放内存,所以当然要把mm的所有引用都干掉);

对于实现的代码细节,不同的版本代码演进较快,之前memcg中会直接调用内核的select_bad_process和oom_kill_process,在最新的3.10中,memcg实现了自己的select_bad_process,即在memcg的代码中自己来找到要杀死的进程。虽然函数调用不同,但是找到要杀死的进程的原理都是类似的,select的过程会给memcg(或及其子memcg)下的每个进程打一个分,得分最高者被选中。评分因素每个版本不尽相同,主要会考虑以下因素:

a.     进程拥有page和swap entry越多,分得越高;

b.    可以通过/proc/$pid/oom_score_adj进行一些分值干预;

c.     拥有CAP_SYS_ADMIN的root进程分值会被调低;

 

kill的过程比较简单,简单的说就是向要杀死的进程发送SIGKILL信号,但其中依然有一些细节:

a.     如果被选中的进程有一些子进程跟他不共用同一个mm,并且也是可以被杀死的,那么就挑选这些子进程中badness得分最高的一个来代替父进程被杀死,这样是为了确保我们在释放内存的同时失去更少的东西;

b.    上面已经说了,oom_kill的过程会杀死选中的进程及与其共用mm的进程,所以会遍历所有用户态进程,找到并杀死与选中进程共用同一个mm的进程;

c.     遍历进程的过程中,会过滤掉通过/proc/$pid/oom_score_adj干预的不可被oom_kill掉的进程(目前是设置为OOM_SCORE_ADJ_MIN的进程);

 

在oom的过程中,另外值得一说的是其中的同步过程。

oom过程会向选中的进程发送SIGKILL信号,但是距离进程处理信号、释放空间,还是需要经历一定时间的。如果系统负载较高,则这段时间内很可能有其他上下文也需要却得不到page,而触发新的oom。那么如果大量oom在短时间内爆发,可能会大面积杀死系统中的进程,带来一场浩劫。

所以oom过程需要同步:在给选中的进程发送SIGKILL后,会设置其TIF_MEMDIE标记。而在select被杀死进程的过程中如果发现记有TIF_MEMDIE的进程,则终止当前的oom过程,并等待上一个oom过程结束。这样做可以避免oom时大面积的kill进程。

而在进程退出时,会先将task->mm置为NULL,再mmput(mm)释放掉引用计数,从而导致内存空间被释放(如果引用计数减为0的话)。所以,只要task->m

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值