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-rss
VSZ 表示进程分配的虚拟内存
VSZ 包括进程可以访问的所有内存,包括进入交换分区的内容,以及共享库占用的内存。
其他:
- cgroups v1 中通过
/sys/fs/cgroup/memory
控制
控制系统 OOM 的参数
/proc/sys/vm/panic_on_oom
panic 时是否触发 OOM,候选值0
表示启动 OOM killer,通过/proc/sys/vm/oom_kill_allocating_task
判断杀死哪些进程1
表示有可能会触发kernel panic(内核崩溃)
,也有可能启动OOM killer
2
表示强制触发kernel panic
kernel panic 10 秒后自动重启系统:
echo "kernel.panic=10" >> /etc/sysctl.conf
/proc/sys/vm/oom_kill_allocating_task
0
表示 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_memorys
Linux 允许进程在申请内存的时候是允许 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_adj
oom_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-disable
Disable OOM Killer--oom-score-adj int
Tune 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
|
|