一、什么是oom_killer
oom_killer(out of memory killer)是Linux内核的一种内存管理机制,在系统可用内存较少的情况下,内核为保证系统还能够继续运行下去,会选择杀掉一些进程释放掉一些内存。
二、oom_killer触发流程
触发流程:进程A想要分配物理内存->触发缺页异常->内核分配物理内存->物理内存不够,触发OOM
当系统发现内存不足以分配新的内存请求时,系统会尝试直接内存回收。这种情况下,如果回收完文件页和匿名页后,内存够用了,当然皆大欢喜,把回收回来的内存分配给进程就可以了。
但如果内存还是不足,OOM 就要登场了。
OOM 机制按照 oom_score 给进程排序。oom_score 越大,进程就越容易被系统杀死。一个进程消耗的内存越大,oom_score 就越大
OOM 发生时,你可以在message 中看到 Out of memory 的信息,从而知道是哪些进程被 OOM 杀死了。
当然了,如果你不希望应用程序被 OOM 杀死,可以调整进程的 oom_score_adj,减小 OOM 分值,进而降低被杀死的概率。
oom_score_adj的取值范围为-1000到1000,-1000代表禁止OOM kill,可以通过往/proc/pid/oom_score_adj文件写入数字进行修改
三、oom_score计算
oom_score = oom_score_adj + 内存消耗 * 1000/总内存
内存消耗:常驻内存RSS + 进程页面 +交换内存
总内存:总的物理内存 +交换分区
1、进程29789信息
# more /proc/29789/oom_score 967 # more /proc/29789/oom_score_adj 937 # pidstat -r -p 29789 Linux 3.10.0-1062.9.1.el7.x86_64 10/26/2020 _x86_64_ (16 CPU) 03:31:35 PM UID PID minflt/s majflt/s VSZ RSS %MEM Command 03:31:35 PM 0 29789 0.13 0.00 5638548 993376 3.02 java # awk '/Swap:/{a=a+$2}END{print a}' /proc/29789/smaps 0
oom_score:967
oom_score_adj:937
RSS:993376
swap:0
页表本身占用很少,在此忽略
2、操作系统信息
# free total used free shared buff/cache available Mem: 32944336 15146876 1236748 1625544 16560712 15769096 Swap: 0 0 0
memory total:32944336
swap:0
3、计算
oom_score = oom_score_adj + (常驻内存RSS + 进程页面 +交换内存) * 1000/(总的物理内存 +交换分区)
oom_score = 937 + (993376+0)*1000/(32944336+0)= 967
四、相关参数
1、vm.panic_on_oom:
0:当内存耗尽时,内核会触发OOM killer杀掉最耗内存的进程。
1:表示关闭此功能,内核直接panic
2、vm.oom_kill_allocating_task
0:内核检查每个进程的分数,分数最高的进程将被kill掉
1:内核将kill掉当前申请内存的进程