何为OOM Killer
内核检测到系统内存不足、挑选并杀掉某个进程,挑选的过程就是打分的过程,挑选的算法和想法都很简单很朴实:最 bad 的那个进程就是那个最占用内存的进程。
root 权限的进程通常被认为很重要,不应该被轻易杀掉,所以打分的时候可以得到 3% 的优惠(adj -= 30; 分数越低越不容易被杀掉
OOM KILLER 行为控制
单个进程层面
# echo -1000 > /proc/<pid>/oom_score_adj
# echo -17 > /proc/<pid>/oom_adj
数值越小,越不容易被kill,-17和-1000代表永远不会被kill
操作系统层面
# sysctl -w vm.panic_on_oom=1 // 1表示关闭,默认为0表示开启OOM
# echo "vm.panic_on_oom = 1" >> /etc/sysctl.conf
# sysctl -w kernel.panic=10 //10秒后自动重启系统
# echo "kernel.panic=10" >> /etc/sysctl.conf
# sysctl -p
oom 体现
系统资源
内存几乎耗尽
Log
grep -i oom-killer /var/log/syslog // /var/log/syslog 会定时清理
权重打分文件
主要根据前两个文件决定杀死哪一个进程的
- /proc/
/oom_score_adj
-1000到1000,数值越小,kill概率越小,-1000不能被kill
- /proc/
/oom_score
-17到15,数值越小,kill概率越小,-17不能被kill
- /proc/
/oom_adj
为了和旧版本的内核兼容
完全关闭 OOM KILLER 机制
# sysctl -w vm.overcommit_memory=2
# echo "vm.overcommit_memory=2" >> /etc/sysctl.conf
防止第三方程序被oom killer
例如 mysqld
cronta -e
···
*/1**** pgrep -f "mysqld" | while read PID;do echo -17 > /proc/$PID/oom_adj;done
···
# 开机自启
echo -17 > /proc/$(pidof mysqld)/oom_adj
例子
虚拟内存占用40G,常驻内存占用9G的一个MySQL
$ cat /proc/11133/oom_score
288
$ cat /proc/11133/oom_score_adj
0
$ cat /proc/11133/oom_adj
0
查看系统全部的(去重+排序)
root@ali:/proc# find /proc -name "oom_score" -type f -exec cat {} \; | sort | uniq |sort -n
0
1
2
3
4
5
6
8
15
20
25
29
31
43
45
46
72
98
111
160
Link
https://dev.to/rrampage/surviving-the-linux-oom-killer-2ki9
https://learning-kernel.readthedocs.io/en/latest/mem-management.html
https://segmentfault.com/a/1190000008268803
可以哦,这个博客是用go写的么?
不是的 -。--