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


28

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

我已禁用OOM杀死功能并使用sysctl vm.overcommit_memory = 2来过量使用。

VM具有3 GB的绝对免费的无碎片交换,并且被OOM杀死的进程的最大内存使用量小于200MB。

我知道长期交换对于性能而言将是可怕的,但是我现在需要使用交换来在内存需求更大的valgrind下进行功能测试。

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

8
从调用跟踪可以明显看出内核没有足够的内存。至于为什么不交换,可能有许多不同的原因,所有的原因都太长了,无法完全解释500个字符。但是您的页面看起来好像没有可回收的页面(all_unreclaimable是的)。这些页面被锁定在RAM中,通常是因为它们已被钉住或被内核使用。那时,您在RAM中留下的所有内容都无法交换。本来可以交换的一切都已经存在。同样,解决方案是增加RAM。
迈克尔·汉普顿

1
@MichaelHampton常规应用程序正在使用其余的内存。内核为什么不能推动它们交换?请回答我的问题“如果您说的是真的,那么在使用了所有物理内存之后,任何进程怎么会分叉?”
编码器

1
@MichaelHampton我禁用了派生,现在fail2ban调用了oom killer,导致我的进程被杀死。如果内核不使用交换功能,那有什么意义呢?更重要的是,如何配置内核,以使其不再耗尽内存。
编码器

4
@MatthewIfe:如果您知道答案,请在此处发布。Stack Exchange网站不仅为提出问题的OP带来好处,而且还为所有阅读者带来了好处。
R.,

4
在虚拟机中交换不被视为最佳实践。为您的VM分配更多的实际内存。如果您不能添加更多的内存,则将其内部添加到物理硬件中,而不要将其留给小型机。
Criggie'3

Answers:


36

结合两个因素,这似乎是一个问题:

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

这部分是描述发生这种情况的方式之一:

3月7日02:43:11 myhost内核:memcheck-amd64-调用的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(通常Normal在x86_64上也被称为)倾向于将内存映射到标准896MiB范围之外的区域,这些区域可直接在32位系统上进行内核访问。在x86_64上,HighMem/Normal似乎可以覆盖3GiB以上的所有页面。

DMA32包含一个用于32位DMA设备可访问的内存区域,即您可以使用4字节指针对其进行寻址。我相信DMA适用于16位DMA设备。

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

您OOM终止的原因是因为有HighMem0页可用区域的内存分配。鉴于内存不足处理程序绝对无法通过交换,杀死其他进程或任何其他技巧来使该区域具有要使用的页面,因此OOM-killer只会杀死它。

我认为这是由于启动时主机VM膨胀引起的。在KVM系统上,可以设置两个值。

  • 当前内存。
  • 可用内存。

它的工作方式是可以将内存热添加到服务器,直到可用内存。但是实际上为您的系统提供了当前内存。

当KVM VM启动时,它从可能分配的最大内存(可用内存)开始。逐渐地,在系统启动阶段,KVM使用其气球膨胀来收回该内存,而使您拥有当前的内存设置。

我的信念是这里发生了什么。Linode允许您扩展内存,在系统启动时为您提供更多功能。

这意味着Normal/HighMem在系统寿命开始时会有一个区域。当虚拟机管理程序迅速消失时,正常区域将从内存管理器中消失。但是,我怀疑设置该区域是否可从中进行分配的标志没有在应有的时候被清除。这导致内核尝试从不存在的区域进行分配。

在解决此问题方面,您有两个选择。

  1. 将其放在内核邮件列表中,以查看这是否确实是错误,预期的行为或与我所说的无关。

  2. 要求linode将系统上的“可用内存”设置为与“当前内存”相同的1GiB分配。因此,系统从不膨胀,也不会在引导时进入正常区域,从而使标志保持清晰。祝他们好运!

您应该能够通过在可用的6GiB,当前为1GiB的KVM设置中设置自己的VM并使用相同的内核运行测试来查看是否出现这种情况,来测试这种情况。如果是这样,请将“ available”设置更改为等于1GiB电流,然后重复测试。

我在这里进行了一些有根据的猜测,并在两行之间进行了一些阅读,以得出这个答案,但是我说的似乎符合已经概述的事实。

我建议检验我的假设,并让我们所有人都知道结果。


4
这是一个彻底的(而且解释清楚)的答案!
奥利维尔·杜拉克

2
是的,很好的答案...比人们的评论“ OP应该盲目地信任内核消息”更有帮助,而没有试图解释为什么不使用可用交换空间的想法。
Michael Martinez

31

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

/ proc / [pid] / oom_score_adj(自Linux 2.6.36起)此文件可用于调整错误启发式,用于选择在内存不足的情况下杀死哪个进程...

/ proc / [pid] / oom_adj(从Linux 2.6.11开始),该文件可用于调整分数,该分数用于选择在内存不足(OOM)情况下应杀死哪个进程...

还有很多要阅读的内容,但是将oom_score_adj设置为-1000或将oom_adj设置为-17将会达到您想要的目的。

麻烦是其他东西将被杀死。确定为什么要调用OOM并进行处理可能会更好。


4
+1表示“解决基本问题”。可能有问题的软件(或其他东西)刚刚尝试分配了很大一部分内核?要求更多的内存,这将使事情进入红色警报领域,这往往会触发OOM杀手。
MadHatter

11
@Coder:Linux内核程序员和Linux内核显然比您了解更多。您的进程被杀死是因为(尽管您进行了抗议)内存不足。如果您认为这不正确,请提交错误报告。如果您不打算听那些知识渊博的人所说的话,那么也许您应该为您的支持付费,因为忠告是值得的。该建议不会有所不同,但您会为此付费,因此会更加珍惜。
user9517支持GoFundMonica

4
@Coder,我不是程序员,可悲的是。只是介于两种可能性之间:内核不知道如何使用VM,以及程序员犯了一个错误,我知道我的钱在哪。
MadHatter在2013年

1
@coder我是“某人”。让我知道如何取得联系。
马修·伊夫,2016年

1
我可以告诉您,从运行数千个linux系统的@MadHatter来看:并非不可能假设内存管理或内核的任何其他部分都没有问题。这是不是像一个高档UNIX平台,而一切都正常工作就好这是理智的采取任何一方以任何教条的方式。
Florian Heigl

12

几点想法(来自我上面的评论),以及一些有关您所处情况的有趣链接:


1
oom_adj仅对较旧的内核有效,较新的内核使用oom_score_adj。
user9517支持GoFundMonica

免责声明:除了上面的几个链接,我无法提供更多详细的信息,因为目前我无法访问linux系统...而且有很多事情需要检查。也许有人会介入并提供良好的分步程序...(serverfault答案,我答案中的“好读”链接的最后一个,就像那样,真是令人难以置信的阅读。)
Olivier Dulac

6

除了提到oom_score_adj增加有问题的进程外(这可能无济于事,这将使该进程被首先杀死的可能性降低,但是因为这只是内存密集型的进程系统可能要等到最后才能恢复已杀死),以下是一些需要调整的想法:

  • 如果设置vm.overcommit_memory=2,也可以调整vm.overcommit_ratio为90(或者,设置vm.overcommit_memory=0-请参阅内核过量提交文档
  • 增加vm.min_free_kbytes以始终保持一些物理RAM可用,从而减少OOM需要杀死某些内容的可能性(但不要过度使用它,因为它会立即使OOM消失)。
  • 增加到vm.swappiness100(使内核交换更容易

请注意,如果您的内存不足以完成手头的任务,即使您没有OOM,它也可能(或可能不会)变得非常慢-半小时的工作(在具有足够RAM的系统上)可能会花费数周的时间(当RAM替换为swap时)在极端情况下完成,甚至挂起整个VM。如果由于大量随机读取/写入而在经典旋转磁盘(而不是SSD)上进行交换的情况下尤其如此,则交换非常昂贵。


3

我会尝试启用过量使用,看看是否有帮助。您的进程似乎在一次fork调用中失败,这需要与初始进程一样多的虚拟内存。overcommit_memory=2不能使您的进程不受OOM杀手的侵害,它只是通过分配过多来阻止您的进程触发它。其他进程可能会产生不相关的分配错误(例如,获取连续的内存块),这些错误仍然会触发OOM杀手并处理您的进程。

另外,正如一些评论所建议的那样(更多的要点),购买更多的RAM。


0

简短的故事-尝试使用其他内核版本。我的系统在4.2.0-x和4.4.0-x内核中显示OOM错误,但在3.19.0-x中却没有。

长话短说:(不算太长!)我还在这里使用Compaq DC5000-目前具有512MB的RAM(其中的一部分,例如32-128MB,已提供给板载视频。) NFS,我确实有一个监视器连接到它,所以偶尔我会登录它(Ubuntu Classic,没有Unity。)

通过Ubuntu HWE,我运行3.19.x内核已经有一段时间了。它最终将交换出200-300MB的内容,但显然它是未使用的内容,据我所知,它以后不会进行任何交换活动。

在4.2.0-x内核和现在的4.4.0-x内核中,我可以开始对它进行大块的NFS写入,只有220MB的空间可以插入交换空间(即1.3GB可用空间),这将开始使OOM崩溃。我不会声称这是内核错误还是“调整问题”(例如正常情况下可以保留64MB的存储空间,但在约400MB的系统上容量过高?)

对于那些说仅仅因为他希望使用交换功能而以某种方式中断的人,他并不无礼。出于所有应有的尊重,您错了。它不会很快,但是我曾经在一些512MB-1GB系统上使用1GB或2GB的交换空间。当然,某些类型的软件mlock只是一堆RAM,但就我而言(因为我在不同的内核上运行相同的软件)显然不是这种情况。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.