首先了解一下什么是oom killer?
简单理解是, Linux内核里出于保护其他资源,不致于让系统立刻崩溃,采取了一种保护进程手段,当linux系统所剩的内存空间不足以满足系统正常运行时,把使用内存异常服务进行kill。
具体而言,oom killer的操作,主要有以下步骤:当系统内存不足的时候,out_of_memory()被触发,然后调用select_bad_process()选择一个”bad”进程杀掉。如何判断和选择一个”bad进程呢?linux选择”bad”进程是通过调用oom_badness(),挑选的算法和想法都很简单很朴实:最bad的那个进程就是那个最占用内存的进程。
参考内核源代码linux/mm/oom_kill.c
https://github.com/torvalds/linux/blob/master/mm/oom_kill.c
https://elixir.free-electrons.com/linux/v2.6.18/source/mm/oom_kill.c
什么时候触发oom_kill.c?
从名称上看就是要发生out_of_memory(),如果检查到内存不足,则触发OOM机制。OOM首先会对系统所有进程(出init和内核线程等特殊进程)进行打分,并选出最bad的进程;然后杀死该进程。
out_of_memory()核心几行代码,主要是:
void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask,
int order, nodemask_t *nodemask, bool force_kill)
{
...
p = select_bad_process(&points, totalpages, mpol_mask, force_kill);
if (!p) {
dump_header(NULL, gfp_mask, order, NULL, mpol_mask);
panic("Out of memory and no killable processes...\n");
}
// kill掉被选中的进程,以释放内存。
if (PTR_ERR(p) != -1UL) {
oom_kill_process(p, gfp_mask, order, points, totalpages, NULL,
nodemask, "Out of memory");
killed = 1;
}
}
<