调研目标:
1、检查memory cgroup管理的进程都设置为不可oom kill时,当出现oom,是否会造成进程或进程组阻塞。
2、若出现阻塞,是否可自恢复。
一、准备过程
0、运行lssubsys --all,检查是否安装了cgroup的组件;没有安装则 apt-get install -y cgroup-bin。
1、准备三个程序,其中两个分别可抢占内存256MB、128MB,最后一个可从0开始逐渐增大内存占用。
2、对debian系统打开cgroup memmory子系统。(debian默认是关闭该子系统的)。
操作: vim /etc/default/grub
修改GRUB_CMDLINE_LINUX的值为"cgroup_enable=memory"。保存。
执行update-grub; 执行reboot。
3、创建一个memory限制的cgroup。(执行完步骤2后,memory root cgroup会自动创建并挂载)。
操作: cd /sys/fs/cgroup/memory/
mkdir ts_mem_cg
echo 400M > memroy.limit_in_bytes
二、测试过程
1、在ts_mem_cg下启动进程,并设置为不可oom_kill。
操作:
cgexec -g memory:ts_mem_cg /home/test/256MBMem
cgexec -g memory:ts_mem_cg /home/test/128MBMem
ps aux |grep 256MBMem, 找到pid,echo -1000 > /proc/pid/oom_score_adj
ps aux |grep 128MBMem, 找到pid,echo -1000 > /proc/pid/oom_score_adj
对第三个进程,直接启动/home/test/auto_encrease_mem,该程序会被getchar()阻塞。再打开一个终端界面执行下面的操作。
ps aux |grep auto_encrease_mem, 找到auto_encrease_mem的pid。echo -1000 > /proc/pid/oom_score_adj。
把进程auto_encrease_mem添加到ts_mem_cg: cgclassify -g memory:ts_mem_cg pid
回到第一个终端响应getchar(),让程序开始执行,逐渐抢占内存。(这样操作是为了防止启动后来不及做oom设置就先oom了)。
2、利用top或free观察内存使用情况。
3、auto_encrease_mem程序不断申请内存并输出提示,最后提示信息的输出中断。说明发生了oom。
4、对auto_encrease_mem程序增加printf()输出,多次测试,观察输出提示中断对应的位置。反复测试确认位置。
5、调整128MB进程的oom_score_adj(,改为默认值0和线上值-900),使其变成可oom kill。多次测试,检查cgroup进程组的变化,被阻塞的进程auto_encrease_mem是否能脱离阻塞状态。
三、结果分析
1、多次测试后,发现auto_encrease_mem阻塞在malloc()操作。
此时,三个程序总共占用内存257+129+16=402MB;auto_encrease_mem进程cpu占用53%(top显示)。
2、第5步操作后,进程128MBMem随即被oom kill;进程auto_encrease_mem恢复正常运行(继续申请内存并输出已用内存量提示信息)。
四、结论
1、依据上述测试,认定在memory cgroup限定的内存使用完时(临近oom),如果该cgroup管理的进程都不可oom kill,那么cgroup进程组的进程就有机会在申请内存时被阻塞。
2、如果memory cgroup进程组内有进程可被oom kill,则这些进程在oom发生时会被kill掉。内存空余后,之前因oom被阻塞的进程可以恢复执行。
说明: 以上测试在没有开启swap盘的情况下进行。