如何让Linux OOM杀手不杀我的进程?

当物理内存不足时,如何让Linux OOM杀手不会杀死我的进程,但有足够的交换空间?

我已经禁用了OOM查杀并且用sysctl vm.overcommit_memory = 2过度使用。

虚拟机具有3 GB的完全空闲片段交换,被OOM杀死的进程的最大内存使用量小于200MB。

我知道长期交换对于性能来说是非常糟糕的,但是我现在需要使用交换来在valgrind下进行functiontesting,而内存​​需求要大得多。

Mar 7 02:43:11 myhost kernel: memcheck-amd64- invoked oom-killer: gfp_mask=0x24002c2, order=0, oom_score_adj=0 Mar 7 02:43:11 myhost kernel: memcheck-amd64- cpuset=/ mems_allowed=0 Mar 7 02:43:11 myhost kernel: CPU: 0 PID: 3841 Comm: memcheck-amd64- Not tainted 4.4.0-x86_64-linode63 #2 Mar 7 02:43:11 myhost kernel: Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014 Mar 7 02:43:11 myhost kernel: 0000000000000000 0000000000000000 ffffffff8158cbcc ffff880032d7bc18 Mar 7 02:43:11 myhost kernel: ffffffff811c6a55 00000015118e701d ffffffff81044a8d 00000000000003e2 Mar 7 02:43:11 myhost kernel: ffffffff8110f5a1 0000000000000000 00000000000003e2 ffffffff81cf15cc Mar 7 02:43:11 myhost kernel: Call Trace: Mar 7 02:43:11 myhost kernel: [<ffffffff8158cbcc>] ? dump_stack+0x40/0x50 Mar 7 02:43:11 myhost kernel: [<ffffffff811c6a55>] ? dump_header+0x59/0x1dd Mar 7 02:43:11 myhost kernel: [<ffffffff81044a8d>] ? kvm_clock_read+0x1b/0x1d Mar 7 02:43:11 myhost kernel: [<ffffffff8110f5a1>] ? __raw_callee_save___pv_queued_spin_unlock+0x11/0x1e Mar 7 02:43:11 myhost kernel: [<ffffffff81183316>] ? oom_kill_process+0xc0/0x34f Mar 7 02:43:11 myhost kernel: [<ffffffff811839b2>] ? out_of_memory+0x3bf/0x406 Mar 7 02:43:11 myhost kernel: [<ffffffff81187bbd>] ? __alloc_pages_nodemask+0x8ba/0x9d8 Mar 7 02:43:11 myhost kernel: [<ffffffff811b82e8>] ? alloc_pages_current+0xbc/0xe0 Mar 7 02:43:11 myhost kernel: [<ffffffff811b096c>] ? __vmalloc_node_range+0x12d/0x20a Mar 7 02:43:11 myhost kernel: [<ffffffff811e0e62>] ? alloc_fdtable+0x6a/0xd8 Mar 7 02:43:11 myhost kernel: [<ffffffff811b0a83>] ? __vmalloc_node+0x3a/0x3f Mar 7 02:43:11 myhost kernel: [<ffffffff811e0e62>] ? alloc_fdtable+0x6a/0xd8 Mar 7 02:43:11 myhost kernel: [<ffffffff811b0ab0>] ? vmalloc+0x28/0x2a Mar 7 02:43:11 myhost kernel: [<ffffffff811e0e62>] ? alloc_fdtable+0x6a/0xd8 Mar 7 02:43:11 myhost kernel: [<ffffffff811e1338>] ? dup_fd+0x103/0x1f0 Mar 7 02:43:11 myhost kernel: [<ffffffff810dd143>] ? copy_process+0x5aa/0x160d Mar 7 02:43:11 myhost kernel: [<ffffffff8110f5a1>] ? __raw_callee_save___pv_queued_spin_unlock+0x11/0x1e Mar 7 02:43:11 myhost kernel: [<ffffffff810de2fc>] ? _do_fork+0x7d/0x291 Mar 7 02:43:11 myhost kernel: [<ffffffff810ea186>] ? __set_current_blocked+0x47/0x52 Mar 7 02:43:11 myhost kernel: [<ffffffff810ea1f2>] ? sigprocmask+0x61/0x6a Mar 7 02:43:11 myhost kernel: [<ffffffff81998eae>] ? entry_SYSCALL_64_fastpath+0x12/0x71 Mar 7 02:43:11 myhost kernel: Mem-Info: Mar 7 02:43:11 myhost kernel: active_anon:15 inactive_anon:18 isolated_anon:0 Mar 7 02:43:11 myhost kernel: active_file:7 inactive_file:8 isolated_file:0 Mar 7 02:43:11 myhost kernel: unevictable:0 dirty:3 writeback:26 unstable:0 Mar 7 02:43:11 myhost kernel: slab_reclaimable:1798 slab_unreclaimable:3674 Mar 7 02:43:11 myhost kernel: mapped:8 shmem:1 pagetables:752 bounce:0 Mar 7 02:43:11 myhost kernel: free:1973 free_pcp:0 free_cma:0 Mar 7 02:43:11 myhost kernel: Node 0 DMA free:3944kB min:60kB low:72kB high:88kB active_anon:0kB inactive_anon:0kB active_file:28kB inactive_file:32kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15992kB managed:15908kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:72kB slab_unreclaimable:236kB kernel_stack:48kB pagetables:60kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:36 0 all_unreclaimable? yes Mar 7 02:43:11 myhost kernel: lowmem_reserve[]: 0 972 972 972 Mar 7 02:43:11 myhost kernel: Node 0 DMA32 free:3948kB min:3956kB low:4944kB high:5932kB active_anon:60kB inactive_anon:72kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:1032064kB manag ed:999552kB mlocked:0kB dirty:12kB writeback:104kB mapped:32kB shmem:4kB slab_reclaimable:7120kB slab_unreclaimable:14460kB kernel_stack:2112kB pagetables:2948kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_t mp:0kB pages_scanned:792 all_unreclaimable? yes Mar 7 02:43:11 myhost kernel: lowmem_reserve[]: 0 0 0 0 Mar 7 02:43:11 myhost kernel: Node 0 DMA: 20*4kB (UM) 17*8kB (UM) 13*16kB (M) 14*32kB (UM) 8*64kB (UM) 4*128kB (M) 4*256kB (M) 0*512kB 1*1024kB (M) 0*2048kB 0*4096kB = 3944kB Mar 7 02:43:11 myhost kernel: Node 0 DMA32: 934*4kB (UM) 28*8kB (UM) 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 3960kB Mar 7 02:43:11 myhost kernel: 71 total pagecache pages Mar 7 02:43:11 myhost kernel: 42 pages in swap cache Mar 7 02:43:11 myhost kernel: Swap cache stats: add 245190, delete 245148, find 77026/136093 Mar 7 02:43:11 myhost kernel: Free swap = 3118172kB Mar 7 02:43:11 myhost kernel: Total swap = 3334140kB Mar 7 02:43:11 myhost kernel: 262014 pages RAM Mar 7 02:43:11 myhost kernel: 0 pages HighMem/MovableOnly Mar 7 02:43:11 myhost kernel: 8149 pages reserved Mar 7 02:43:11 myhost kernel: [ pid ] uid tgid total_vm rss nr_ptes nr_pmds swapents oom_score_adj name Mar 7 02:43:11 myhost kernel: [ 2054] 0 2054 5101 1 15 4 283 0 upstart-udev-br Mar 7 02:43:11 myhost kernel: [ 2063] 0 2063 12362 1 28 4 184 -1000 systemd-udevd Mar 7 02:43:11 myhost kernel: [ 3342] 102 3342 9780 1 23 3 89 0 dbus-daemon Mar 7 02:43:11 myhost kernel: [ 3423] 0 3423 10864 1 26 3 85 0 systemd-logind Mar 7 02:43:11 myhost kernel: [ 3441] 0 3441 15344 0 34 3 184 -1000 sshd Mar 7 02:43:11 myhost kernel: [ 3450] 0 3450 4786 0 14 3 43 0 atd Mar 7 02:43:11 myhost kernel: [ 3451] 0 3451 5915 0 17 4 65 0 cron Mar 7 02:43:11 myhost kernel: [ 3457] 101 3457 63962 0 28 3 202 0 rsyslogd Mar 7 02:43:11 myhost kernel: [ 3516] 0 3516 3919 1 13 3 156 0 upstart-file-br Mar 7 02:43:11 myhost kernel: [ 3518] 0 3518 4014 0 13 3 265 0 upstart-socket- Mar 7 02:43:11 myhost kernel: [ 3557] 0 3557 66396 0 32 3 1802 0 fail2ban-server Mar 7 02:43:11 myhost kernel: [ 3600] 0 3600 3956 1 13 3 39 0 getty Mar 7 02:43:11 myhost kernel: [ 3601] 0 3601 3198 1 12 3 37 0 getty Mar 7 02:43:11 myhost kernel: [ 3673] 0 3673 26411 1 55 3 252 0 sshd Mar 7 02:43:11 myhost kernel: [ 3740] 1000 3740 26411 1 52 3 253 0 sshd Mar 7 02:43:11 myhost kernel: [ 3741] 1000 3741 5561 0 16 3 431 0 bash Mar 7 02:43:11 myhost kernel: [ 3820] 103 3820 7863 1 21 3 152 0 ntpd Mar 7 02:43:11 myhost kernel: [ 3837] 1000 3837 31990 0 58 4 12664 0 memcheck-amd64- Mar 7 02:43:11 myhost kernel: [ 3841] 1000 3841 32006 0 59 4 12812 0 memcheck-amd64- Mar 7 02:43:11 myhost kernel: [ 3844] 1000 3844 31950 0 57 4 12035 0 memcheck-amd64- Mar 7 02:43:11 myhost kernel: [ 3849] 1000 3849 31902 0 56 4 11482 0 memcheck-amd64- Mar 7 02:43:11 myhost kernel: [ 3853] 1000 3853 1087 0 7 3 27 0 lsof Mar 7 02:43:11 myhost kernel: [ 3854] 0 3854 26140 5 55 3 230 0 sshd Mar 7 02:43:11 myhost kernel: [ 3855] 104 3855 15699 0 33 3 202 0 sshd Mar 7 02:43:11 myhost kernel: Out of memory: Kill process 3841 (memcheck-amd64-) score 11 or sacrifice child Mar 7 02:43:11 myhost kernel: Killed process 3841 (memcheck-amd64-) total-vm:128024kB, anon-rss:0kB, file-rss:0kB 

这是/ proc / meminfo

 MemTotal: 1015460 kB MemFree: 277508 kB MemAvailable: 322032 kB Buffers: 8336 kB Cached: 42208 kB SwapCached: 46088 kB Active: 58844 kB Inactive: 116100 kB Active(anon): 34784 kB Inactive(anon): 89620 kB Active(file): 24060 kB Inactive(file): 26480 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 3334140 kB SwapFree: 3215756 kB Dirty: 16 kB Writeback: 0 kB AnonPages: 121128 kB Mapped: 15072 kB Shmem: 4 kB Slab: 22668 kB SReclaimable: 8028 kB SUnreclaim: 14640 kB KernelStack: 2016 kB PageTables: 2532 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 3841868 kB Committed_AS: 380460 kB VmallocTotal: 34359738367 kB VmallocUsed: 0 kB VmallocChunk: 0 kB DirectMap4k: 14208 kB DirectMap2M: 1034240 kB DirectMap1G: 0 kB 

这似乎是两个因素相结合的问题:

  • 使用虚拟机。
  • 一个可能的内核错误。

这部分是描述为什么发生这种情况的一条线:

 Mar 7 02:43:11 myhost kernel:memcheck-amd64-invoked oom-killer:gfp_mask = 0x24002c2,order = 0,oom_score_adj = 0

另一条线是这样的:

 Mar 7 02:43:11 myhost kernel: 0 pages HighMem/MovableOnly 

|第一行是为分配分配的GFP掩码。 它基本上描述了内核被允许/不允许做什么来满足这个请求。 掩码表示一堆标准的标志。 最后一位'2'表示内存分配应该来自HighMem区域。

如果仔细观察OOM输出,您将看不到实际存在的HighMem/Normal区域。

 Mar 7 02:43:11 myhost kernel: Node 0 DMA: 20*4kB (UM) 17*8kB (UM) 13*16kB (M) 14*32kB (UM) 8*64kB (UM) 4*128kB (M) 4*256kB (M) 0*512kB 1*1024kB (M) 0*2048kB 0*4096kB = 3944kB Mar 7 02:43:11 myhost kernel: Node 0 DMA32: 934*4kB (UM) 28*8kB (UM) 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 3960kB 

HighMem (通常在x86_64上也称为Normal )倾向于将内存映射到标准896MiB范围之外的区域,而直接在32位系统上可以访问内核。 在x86_64上, HighMem/Normal似乎覆盖了HighMem/Normal以上的所有页面。

DMA32包含一个用于内存的区域,可以在32位DMA设备上访问,也就是说,您可以使用4个字节的指针来访问它们。 我相信DMA是用于16位DMA设备的。

一般来说,在内存不足的系统上Normal将不存在,因为DMA32已经覆盖了所有可用的虚拟地址。

OOM杀死的原因是因为有一个可用0页的HighMem区域的内存分配。 鉴于内存不足处理程序绝对没有办法满足使这个区域通过交换使用页面,杀死其他进程或任何其他技巧,OOM杀手只是杀死它。

我相信这是由主机虚拟机启动引起的。 在KVM系统上,您可以设置两个值。

  • 目前的记忆。
  • 可用内存。

这样做的方式是,你可以热添加内存到你的服务器,直到可用内存。 然而,你的系统实际上是给予当前的记忆。

当一个KVM虚拟机启动时,它将从可能的最大内存分配开始(可用内存)。 在系统启动阶段逐渐地KVM利用它的膨胀来回收这个内存,而不是使用当前的内存设置。

我相信这就是发生在这里的事情。 Linode允许你扩展内存,给你更多的系统启动。

这意味着在系统生命周期开始时有一个Normal/HighMem区域。 当pipe理程序放空它时,正常区正确地从内存pipe理器中消失。 但是,我怀疑标志设置是否该区域是可用的分配从应该清除。 这导致内核尝试从不存在的区域分配。

在解决这个问题上,你有两个select。

  1. 把它放在内核邮件列表上,看看这是否是一个错误,期望的行为或根本就没有做什么。

  2. 请求linode将系统上的“可用内存”设置为与“当前内存”相同的1GiB分配。 因此,系统不会启动,也不会在启动时获得正常区域,保持标志清晰。 祝你好运,让他们这样做!

你应该可以通过在KVM设置中设置自己的虚拟机来testing这种情况,可以使用6GiB,当前为1GiB,并使用相同的内核运行testing,看看是否出现上述情况。 如果是,请将“可用”设置更改为等于1GiB电stream并重复testing。

我在这里进行了一系列有教育意义的猜测,并在两者之间阅读了一些有关这个答案,但我所说的似乎符合已经概述的事实。

我build议testing我的假设,让我们都知道结果。

要回答您的标题问题,请使用oom_score_adj (内核> = 2.6.36)或更早的内核(> = 2.6.11) oom_adj ,请参阅man proc

/ proc / [pid] / oom_score_adj(从Linux 2.6.36开始)这个文件可以用来调整坏的启发式,用来select哪个进程在内存不足的情况下被终止。

/ proc / [pid] / oom_adj(从Linux 2.6.11开始)这个文件可以用来调整分数,用来select哪个进程应该在内存不足(OOM)的情况下被终止。

还有很多东西需要阅读,但是将oom_score_adj设置为-1000,或者将oom_adj设置为-17就可以达到你想要的效果。

麻烦是别的东西会被杀死。 也许最好是确定为什么OOM被引用和处理。

几个想法(从我上面的评论),以及interresting链接你的情况的链接:

  • 我build议你检查1)你可以使用你当前的内核和configuration(&cpu)超过3Gb,因为如果3Gb是你的系统和操作系统的限制,你就超过了它。 2)您允许交换,交换子系统就位并正常工作。 祝你好运(我不会解释如何,因为这取决于你的设置和具体情况,search引擎会有所帮助)。 而且你没有溢出一个内核表(nb的pid?或其他任何东西(有些可以在内核编译时设置)。

  • 检查整个事情(硬件,或VM的模拟硬件等)是64位。 (请参阅: https : //askubuntu.com/questions/313379/i-installed-a-64-bit-os-in-a-32-bit-processor/313381 )。 CPU和主机操作系统和虚拟机子系统和操作系统应该都是64位启用,否则你将不会有一个真正的64位虚拟机

  • 一些好的内容:

  • 最后: http : //www.oracle.com/technetwork/articles/servers-storage-dev/oom-killer-1911807.html显示了一种方法来防止你的进程成为OOM杀手的目标! ( echo -17 > /proc/PROCESSPID/oom_adj )。 可能容易发生变化,并可能是一个坏事(导致其他types的失败,因为系统现在不能简单地杀死主要犯罪者…)谨慎使用。 @iain注意到“oom_adj”是用于较旧的内核,应该用新的“oom_score_adj”代替。 谢谢,Iain)

除了提到的oom_score_adj增加的问题的进程(这可能不会有太大的帮助 – 这将使这个进程不太可能被杀死FIRST,但因为这只是内存密集型进程系统可能不会恢复,直到它终于遇难),这里有几个想法来调整:

  • 如果你设置vm.overcommit_memory=2 ,也可以调整vm.overcommit_ratio为90(或者,设置vm.overcommit_memory=0 – 查看kernel overcommit docs )
  • 增加vm.min_free_kbytes ,以便始终保持一些物理RAM空闲,从而减lessOOM需要杀死某些东西的机会(但不要过度,因为它会立即OOM)。
  • vm.swappiness增加到100(使内核交换更容易 )

请注意,如果您的内存太less而无法完成手头的任务,即使您没有OOM,它也可能 (或不会)变得非常慢 – 半小时工作(在具有足够内存的系统上)可能需要几个星期当RAM被replace掉时)在极端情况下完成,甚至挂起整个虚拟机。 如果交换是在经典的旋转磁盘上(而不是SSD),那么尤其如此,因为大量的随机读取/写入对于它们来说是非常昂贵的。

我会尝试启用overcommit,看看是否有帮助。 你的过程似乎在一个fork调用中失败了,这个过程需要和最初的过程一样多的虚拟内存。 overcommit_memory=2不会使你的进程对OOM杀手不起作用,它只是通过分配过多而阻止你的进程触发它。 其他进程可能会产生不相关的分配错误(例如,获得一个连续的内存块),这仍然会触发OOM杀手,并让你的进程被丢弃。

另外(更重要的),如几个意见所build议的,购买更多的内存。

小故事 – 尝试一个不同的内核版本。 我有一个系统,用4.2.0-x和4.4.0-x内核显示OOM错误,但是没有显示3.19.0-x。

长篇小说:(不要太长时间了!)我的康柏DC5000还在使用中 – 现在有512MB的内存(还有一部分内存,比如32-128MB,给了机载video..) NFS,我有一个监视器连接到它,所以偶尔我会login到它(Ubuntu的经典,没有团结。)

通过Ubuntu HWE我运行3.19.x内核很长一段时间; 它最终会换成200-300MB的东西,但显然这是没有用的东西,不会有任何交换活动,它不得不在晚些时候交换它,据我所知。

4.2.0-x内核和现在的4.4.0-x内核,我可以启动一个简单的NFS写入它,只有220MB的交换(即1.3GB免费),它会启动OOM杀死的东西。 我不会声称这是一个内核错误还是“调优问题”(比如一个64MB的储备通常很好,但是在大约400MB左右的系统上太高了)?

没有不尊重那些正在说因为他期望使用交换而以某种方式突破的人; 充分尊重你错了。 它不会很快,但是我曾经在几个512MB-1GB的系统上使用1或2GB进入交换。 当然有些types的软件mlock的一堆内存,但在我的情况(因为我只是在不同的内核上运行相同的软件)显然不是这样的情况。