今天早上回到公司,发现某个服务器游戏进程挂了,第一想到的是云服务器宿主机宕机导致被重启了(因为之前遇到过两次)

于是立马登录服务器上查看,首先查看进程日志确定进程被kill时间点,然后查看内核日志/var/log/message发现如下

图片.png

确定是内存不足导致系统触发OOM-killer机制,把进程给kill掉了。


下面分享下OOM-killer的机制:

收集于以下地址:

https://blog.csdn.net/lidan3959/article/details/17350711

https://blog.csdn.net/hunanchenxingyu/article/details/26271293


Linux下允许程序申请比系统可用内存更多的内存,这个特性叫Overcommit。

这样做是出于优化系统考虑,因为不是所有的程序申请了内存就立刻使用的,当你使用的时候说不定系统已经回收了一些资源了。

不幸的是,当你用到这个Overcommit给你的内存的时候,系统还没有资源的话,OOM killer就跳出来了。

为了保护重要进程不被oom-killer掉,我们可以:echo -17 > /proc/<pid>/oom_adj,-17表示禁用OOM

我们也可以对把整个系统的OOM给禁用掉:

sysctl -w vm.panic_on_oom=1 (默认为0,表示开启)

sysctl -p

参数/proc/sys/vm/overcommit_memory可以控制进程对内存过量使用的应对策略

当overcommit_memory=0 允许进程轻微过量使用内存,但对于大量过载请求则不允许(默认)

当overcommit_memory=1 永远允许进程overcommit

当overcommit_memory=2 永远禁止overcommit

Linux下这个选择策略也一直在不断的演化。作为用户,我们可以通过设置一些值来影响OOM killer做出决策。Linux下每个进程都有个OOM权重,在/proc/<pid>/oom_adj里面,取值是-17到+15,取值越高,越容易被干掉。

最终OOM killer是通过/proc/<pid>/oom_score这个值来决定哪个进程被干掉的。这个值是系统综合进程的内存消耗量、CPU时间(utime + stime)、存活时间(uptime - start time)和oom_adj计算出的,消耗内存越多分越高,存活时间越长分越低。

总之,总的策略是:损失最少的工作,释放最大的内存同时不伤及无辜的用了很大内存的进程,并且杀掉的进程数尽量少。