服务器上面运行的weblogic,内存需求很大,虚拟机给了64G内存,但是weblogic总是会不定时被OOM.经观察,每次内存消耗50%的时候,就会被OOM。这明显是不合理的。
刚开始调整了swappiness参数,修改后还是有一定的作用的,但是不久后又出现了OOM。继续查找资料发现如下相关说明。设置后OOM的情况得到了解决。
什么是 OOM_killer
OOM_killer 是Linux自我保护的方式,当内存不足时不至于出现太严重问题,在
kernel 2.6
,内存不足将唤醒 oom_killer,挑出/proc/<pid>/oom_score
最大者并将之kill掉
保护某个进程不被 OOM_killer
为了保护重要进程不被oom-killer掉,我们可以:
echo -17 > /proc/<pid>/oom_adj
-17表示禁用OOM
启用/禁用整个系统的 OOM_killer 策略
sysctl -w vm.panic_on_oom=0
(默认为0:表示启用; 1:表示禁用)
使修改生效sysctl -p
解释
什么是Overcommit和OOM
Linux对大部分申请内存的请求都回复
"yes"
,以便能跑更多更大的程序。因为申请内存后,并不会马上使用内存。这种技术叫做 Overcommit
。
当linux发现内存不足时
,会发生OOM killer(OOM=out-of-memory)。它会选择杀死一些进程(用户态进程,不是内核线程),以便释放内存。
当oom-killer发生时,linux会选择杀死哪些进程?
选择进程的函数是oom_badness函数(在mm/oom_kill.c中),该函数会计算每个进程的点数(0~1000)。点数越高,这个进程越有可能被杀死。每个进程的点数跟oom_score_adj有关,而且 oom_score_adj可以被设置(-1000最低,1000最高)。
控制进程对内存过量使用的应对策略
1 修改配置
- overcommit_memory 是一个内核对内存分配的一种策略。 具体可见
/proc/sys/vm/overcommit_memory
下的值 - 当
overcommit_memory=0
表示即启发式的 overcommitting handle, 会尽量减少swap的使用, root可以分配比一般用户略多的内存 (默认) - 当
overcommit_memory=1
表示允许超过 CommitLimit - 当
overcommit_memory=2
表示不允许超过 CommitLimit
2 查看系统 CommitLimitovercommit_memory
参数就是控制分配内存是否可以超过 CommitLimit
- CommitLimit: 是一个内存分配上限;
CommitLimit = 物理内存 * overcommit_ratio(默认50,即50%
) + swap大小 - Committed_AS: 是已经分配的内存大小
3 配置系统 CommitLimit
通过修改overcommit_ratio
来配置系统 CommitLimit
只有当 vm.overcommit_memory = 2
的时候才会生效