OOM(out of memory)当 Linux 内存使用压力时,Linux 内核会杀掉一些不太重要的进程,通过如下文件判断
现象
OOM 日志一般在 /var/log/syslog、/var/log/message 或 dmesg -T| grep -E -i -B100 'killed process' 中,示例如下:
| |
Linux 内存情况说明
linux中
total-vm(total virtual memory)进程占用的总的虚拟内存RSS(Resident Set Size, 常驻内存集, 驻留内存)表示进程在RAM中占用实际物理内存的大小,并不包含在SWAP中占用的虚拟内存,但包括共享库占用的内存(只要共享库在内存中)anon-rss(anonymous rss, 匿名驻留集)虚拟内存实际占用的物理内存,如malloc的内存file-rss虚拟内存实际占用的磁盘空间,映射到设备和文件上的内存页面shmem-rssVSZ 表示进程分配的虚拟内存
VSZ 包括进程可以访问的所有内存,包括进入交换分区的内容,以及共享库占用的内存。
其他:
- cgroups v1 中通过
/sys/fs/cgroup/memory控制
控制系统 OOM 的参数
/proc/sys/vm/panic_on_oompanic 时是否触发 OOM,候选值0表示启动 OOM killer,通过/proc/sys/vm/oom_kill_allocating_task判断杀死哪些进程1表示有可能会触发kernel panic(内核崩溃),也有可能启动OOM killer2表示强制触发kernel panic
kernel panic 10 秒后自动重启系统:
echo "kernel.panic=10" >> /etc/sysctl.conf/proc/sys/vm/oom_kill_allocating_task0表示 kill 掉得分最高的进程非0表示会 kill 掉当前申请内存而触发OOM的进程,但不会杀死系统进程(如init)或者被用户设置了oom_score_adj的进程
/proc/sys/vm/oom_dump_tasks控制 OOM 时,记录进程标识信息、使用的虚拟内存总量、物理内存、进程的页表信息等等0关闭打印上述日志- 在大型系统中,可能存在有上千个进程,打印使用内存信息可能会造成性能问题
非0有三种情况会打印进程内存使用情况由 OOM 导致 kernel panic 时
没有找到符合条件的进程 kill 时
找到符合条件的进程并 kill 时
/proc/sys/vm/overcommit_memorysLinux 允许进程在申请内存的时候是允许 overcommit,即允许进程申请超过实际物理内存上限的内存
overcommit_memorys 3中策略
0启发式策略比较严重的Overcommit将不能成功,比如突然申请 128TB 的内存
轻微的overcommit将被允许
1永远允许overcommit2永远禁止 overcommit
Linux
malloc有如下描述
| |
OOM score 相关参数
/proc/${pid}/oom_score内核对进程的打分若进程消耗的内存越大,OOM 分数越高,被 OOM 的概率就越大
该参数只反映该进程的可用资源在系统中所占的百分比,并没有该进程有
多重要的概念若进程运行了很长时间,且消耗很多 CPU 时间,通常它的 oom_score 会偏小
/proc/${pid}/oom_score_adj用户对进程的打分,允许用户当遇到内存不足的情况时,通过配置该参数杀死指定进程旧参数为
oom_adj取值范围
[-17, +15],默认值为 0,值越大越容易被 kill 掉设置为 -17(
echo -17 > /proc/$PID/oom_adj) 的话,表示永远禁止 OOM
范围从
-1000(OOM_SCORE_ADJ_MIN)到+1000(OOM_SCORE_ADJ_MAX)-1000表示禁止 OOM killer 杀死该进程echo "-1000" > /proc/$(pidof nginx)/oom_score_adj
计算公式:
min(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)oom = oom_score + oom_score_adjoom_score = 内存消耗(常驻内存RSS+进程页面+交换内存)/总内存(总的物理内存+交换分区)*1000
特殊情况
root 进程拥有
3%的内存使用特权,man choom中有介绍Niced processes are most likely less important, so double their badness points
Processes with CAP_SYS_ADMIN and CAP_SYS_RAWIO,
points /= 4
查看工具
pidstat -r -p <pid>
内核代码
计算 oom
unsigned long oom_badness()找出 oom 最大的进程
static struct task_struct *select_bad_process()发送kill信号关闭进程
oom_kill_process()
使用场景
docker run --help | grep oom--oom-kill-disableDisable OOM Killer--oom-score-adj intTune host’s OOM preferences (-1000 to 1000)
k8s
Guaranteed高优先级BestEffort极低优先级Burstable上述公式计算得到
有用的脚本
打印所以 oom_score 不为 0 的程序
| |
获取 swap 使用量
| |
定期清理缓存
| |
choom
| |
help
man choom
choom –help…
或 man choom 查看详细说明
示例
配合 Supervisord 配置 command 参数
| |
vmstat 1/iostat -x -k 1
vmstat 1 实时监控内存情况
| |
dstat
dstat 查看 OOM score
| |
/proc/meminfo
| |