linux out of memory

逃离我推掉我的手 2021-11-09 10:24 376阅读 0赞

linux out of memery killer

今早登录虚拟 oracle 服务器 出现如下报错

  1. Apr 18 08:35:56 primer kernel: Out of memory: kill process 3718 (oracle) score 94986 or a child
  2. Apr 18 08:35:56 primer kernel: Killed process 3718 (oracle)

这是linux的一种保护机制,用于避免在内存不足的时候不至于出现严重问题,把一些无关的进程优先杀掉,即在内存严重不足时,系统为了继续运转,内核会挑选一个进程,将其杀掉,以释放内存,缓解内存不足情况,不过这种保护是有限的,不能完全的保护进程的运行。

该问题是low memory耗尽,因为内核使用low memory来跟踪所有的内存分配。当low memory耗尽,不管high memory剩多少,oom-killer都会杀死进程,以保持系统的正常运行。

当low memory耗尽,不管high memory剩多少,oom-killer都会杀死进程,以保持系统的正常运行。

在32位CPU下寻址范围是有限的,Linux内核定义了下面三个区域:

  1. # DMA: 0x00000000 - 0x00999999 (0 - 16 MB)
  2. # LowMem: 0x01000000 - 0x037999999 (16 - 896 MB) - size: 880MB
  3. # HighMem: 0x038000000 - <硬件特定>

linux omm 机制

同时这里还涉及到内核当内存耗尽时的一种策略,/proc/sys/vm/overcommit_memory可用于配置这种策略:

overcommit_memory == 2,物理内存使用完后,打开任意一个程序均显示内存不足;

overcommit_memory == 1,会从buffer中释放较多物理内存,oom-kill也会继续起作用;

overcommit_memory ==0,系统默认设置,释放较少物理内存,使得oom-kill机制运作比较明显。

也就是说,如果overcommit_memory==2时,内存耗尽时,oom-kill是不会起作用的,系统不会再打开其他程序了,只有等待正在运行的进程释放内存。

解决办法

修改 omm 策略

添加一下行到/etc/sysctl

  1. #add for omm
  2. vm.overcommit_memory = 1

Linux下每个进程都有个OOM权重,在/proc//oom_adj里面,取值是-17到+15,取值越高,越容易被干掉。

我们可以只针对单一进程处理,把某个进程保护起来,此时,我们可以使用如下命令:

echo -17 > /proc/[pid]/oom_adj

/proc/[pid]/oom_adj中oom_adj的取值范围是-17~15,当该值为-17时,系统将不会杀死指定pid的进程,而-16~15则会使得进程的/proc/[pid]/oom_adj值呈指数(K*2^n)形式递增,即它们被杀掉的可能性呈指数递增。针对init(进程号为1)这个进程,无论该值设为多少都不会被杀。

另外:Linux在计算进程的内存消耗的时候,会将子进程所耗内存的一半同时算到父进程中。这样,那些子进程比较多的进程就要小心了,比如oracle的父进程。

发表评论

表情:
评论列表 (有 0 条评论,376人围观)

还没有评论,来说两句吧...

相关阅读