避免Linux内存不足应用程序崩溃


34

我发现有时候我的Linux机器的内存不足,并且它开始拆除随机进程以对其进行处理。

我很好奇管理员如何避免这种情况?唯一真正增加内存量的解决方案(单独增加交换会有所帮助吗?),还是有更好的方法来设置带有软件的存储盒来避免这种情况?(即配额或其他配额?)。


我在这里找到了答案:serverfault.com/questions/362589/…Patrick的回答很有启发性
Amaury

Answers:


44

默认情况下,Linux具有某种大脑损坏的内存管理概念:它使您可以分配比系统更多的内存,然后在遇到麻烦时随机地将一个进程射向头部。(被杀死的内容的实际语义比这要复杂得多-Google“ Linux OOM Killer”提供了很多有关它是好是坏的细节和论据)。


要使您的内存管理恢复理智的样子:

  1. 禁用OOM Killer(将其vm.oom-kill = 0放在/etc/sysctl.conf中)
  2. 禁用内存过量使用(放入vm.overcommit_memory = 2/etc/sysctl.conf中)。
    请注意,这是一个三进制值:0 =“估计是否有足够的RAM”,1 =“总是说是”,2 =“说否,如果没有”有记忆”)

这些设置将使Linux以传统方式运行(如果某个进程所请求的内存多于可用内存,则malloc()将失败,并且期望该内存的进程可以应对该失败)。

重新引导计算机以使其重新加载/etc/sysctl.conf,或立即使用proc文件系统启用计算机,而无需重新引导:

echo 2 > /proc/sys/vm/overcommit_memory 

11
不是Linux造成了严重的损害,而是分配内存的程序员从未使用过它。Java VM对此臭名昭著。作为管理运行Java应用程序的服务器的管理员,我不会在没有过量使用的情况下生存一秒钟。
Aleksandar Ivanisevic

11
Java程序员不分配未使用的内存,java中没有malloc。我认为您将其与-Xms这样的JVM设置混淆了。在任何情况下,通过添加交换空间来增加虚拟内存大小都是比过量使用更为安全的解决方案。
jlliagre

5
请注意,此解决方案不会阻止系统内存不足或杀死进程。它只会使您恢复传统的Unix行为,如果一个进程吞噬了所有内存,则下一个尝试进行malloc的进程将不会得到任何内存(而且很可能崩溃)。如果您不走运,那么下一个流程就是init(或其他至关重要的流程),OOM Killer通常会避免这样做。
pehrs,2010年

8
jlliagre,我说的是Java VM(虚拟机),而不是Java程序,尽管从管理员的角度来看是一样的:)
Aleksandar Ivanisevic,2010年

8
也许值得一提的是,将以上内容添加到新版本/etc/sysctl.conf可能仅在下次重新启动时生效;如果您现在要进行更改,则应使用sysctl具有root权限的命令,例如sudo sysctl vm.overcommit_memory=2
nickgrim 2012年


3

对于服务器,最简单的答案是购买并安装更多RAM。

常规上足以发生OOM(内存不足)错误,然后在Linux内核中除了VM(虚拟内存)管理器的过量使用sysctl选项之外,这不是一件好事。

如果当前值较低,则增加交换量(已由内核的内存管理器分页到磁盘的虚拟内存)将很有帮助,并且使用情况涉及许多任务,每个任务都需要如此大的内存,而不是一个或几个处理每个请求大量可用总虚拟内存(RAM +交换)的请求。

对于许多分配两倍以上(2x)的应用程序,作为交换的RAM数量会减少改进的回报。在某些大型计算仿真中,如果速度下降是可以忍受的,这可能是可以接受的。

我必须承认,RAM(无论是否使用ECC)对于少量的内存(例如4-16 GB)来说都是可以承受的,我本人已经很长时间没有遇到这个问题了。

查看内存消耗的基础知识,包括使用freetop按内存使用情况排序,这是对内存使用模式的两种最常见的快速评估。因此,请确保至少了解这些命令的输出中每个字段的含义。

由于没有具体的应用程序(例如数据库,网络服务服务器,实时视频处理)和服务器的使用情况(很少的超级用户,100-1000个用户/客户端连接),因此我无法想到任何有关处理的一般建议。 OOM问题。


3

在所有情况下,增加物理内存量可能不是一种有效的措施。

一种检查方法是“ atop”命令。特别是这两行。

运行状况良好时,此服务器已退出服务器:

MEM | tot   23.7G | free   10.0G | cache   3.9G | buff  185.4M | slab  207.8M |
SWP | tot    5.7G | free    5.7G |              | vmcom  28.1G | vmlim  27.0G |

当它运行不佳时(在将overcommit_memory从50调整为90之前,我们会看到vmcom运行超过50G的行为,oom-killer每隔几秒钟就会炸毁一次进程,并且由于NFSd子进程被炸开,负载会从根本上反弹并不断重新创建。

最近,我们重复了一些案例,其中多用户Linux终端服务器大量过量使用虚拟内存分配,但实际上很少消耗所请求的页面。

尽管不建议您遵循此确切路线,但我们将过量使用内存从默认的50调整为90,从而缓解了一些问题。我们最终不得不将所有用户转移到另一台终端服务器,然后重新启动才能看到全部好处。


2

您可以使用ulimit减少进程被杀死之前允许声明的内存量。如果您的问题是一个或几个失控的进程导致服务器崩溃,这将非常有用。

如果您的问题是您根本没有足够的内存来运行所需的服务,则只有三种解决方案:

  1. 通过限制缓存和类似内容来减少服务使用的内存

  2. 创建更大的交换区域。这会降低您的性能,但可以为您带来一些时间。

  3. 购买更多内存


0

我有与此错误相关的类似问题,解决方案是使用旧的/更新的(固定的)内核。

但是,当时我无法重新启动计算机,因此某种丑陋的解决方法是使用root命令登录并使用以下命令清除系统缓存:

echo 3 > /proc/sys/vm/drop_caches

-5

@ voretaq7 linux不具有破坏大脑的内存管理概念,默认情况下vm.overcommit_ratio为0,

0       -   Heuristic overcommit handling. Obvious overcommits of
            address space are refused. Used for a typical system. It
            ensures a seriously wild allocation fails while allowing
            overcommit to reduce swap usage.  root is allowed to
            allocate slightly more memory in this mode. This is the
            default.

这样,如果您有4GB的ram并尝试使用虚拟内存的malloc分配4.2 GB,则分配将失败。

使用vm.overcommit_ratio = 1

            1    -   Always overcommit. Appropriate for some scientific
            applications. Classic example is code using sparse arrays
            and just relying on the virtual memory consisting almost
            entirely of zero pages.

使用vm.overcommit_ratio = 2

           2    -   Don't overcommit. The total address space commit
            for the system is not permitted to exceed swap + a
            configurable percentage (default is 50) of physical RAM.
            Depending on the percentage you use, in most situations
            this means a process will not be killed while accessing
            pages but will receive errors on memory allocation as
            appropriate.

            Useful for applications that want to guarantee their
            memory allocations will be available in the future
            without having to initialize every page.

因此,默认情况下linux不会过量使用,如果您的应用程序拥有更多的内存,那么您的代码可能有错误


2
您在这里自相矛盾。在顶部,您说“默认情况下vm.overcommit_ratio为0”,然后在底部,您说“默认情况下,Linux不会过度使用”。如果后者为true,则vm.overcommit_ratio默认为2!
迈克尔·汉普顿

vm.overcommit_ratio = 0,malloc分配的内存不会比物理内存多,因此对我来说,不要过量使用,过度分配是指您可以分配比物理内存更多的虚拟内存
c4f4t0r

2
是的,您误会了。
迈克尔·汉普顿

你误会了,默认为0,不分配比RAM分配更多虚拟内存和2没过让vm.overcommit_ratio +交换空间,所以如果我误解了告诉我什么
c4f4t0r

2
当然。“明显的过度使用”被拒绝。其余的过去了。您需要仔细阅读。
迈克尔·汉普顿
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.