在Linux上怎么会有一个OOM场景(启发式OOM杀手)?

我知道虚拟内存的概念。 并且需求分页(取决于vm.overcommit_memory),您可以分配比可用RAM更多的内存。 除非你“触摸”一个页面,否则真的没有发生。 否则,我猜是有一个页面错误和物理内存然后用于页面框架。 但是这不知何故意味着,如果系统内存紧张,它只会将最近使用过的东西换出并正常工作。

怎样才能杀死一个进程呢? 这是否发生,因为太多的内存是mlock()。 OOM是在太多垃圾之后被调用的吗? 或者换句话说,触发OOM杀手的背后究竟是什么?

我读了你可以做“回声1> memory.oom_control”或“echo -17> / proc / PID / oom_adj”来禁用它。 那有什么含意? 机器可能会在一段时间内完全没有响应。 但是如果违规程序发现它没有进展,它也可能暂时停止消耗内存(那么快),最终所有的东西都应该重新开始工作,或者我错了吗?

在我的场景中,只有一个进程(具有巨大的内存caching)。 这些数据当然不是持久的,但我宁愿不重新启动进程(并重新加载数据)。

您似乎对虚拟内存和过度使用是如何相关感到困惑。

物理内存由计算机中的RAM芯片组成。 与物理内存相比,在同一时间使用更多的内存在物理上是不可能的。 然而,自从20世纪70年代后期以来,已经存在虚拟内存,其中系统将一些数据从物理内存移动到磁盘,从而存储实际上没有被使用的内存,因此物理内存可以用于其他事物。 发生这种情况时,程序不能立即使用换出的数据。 当他们试图这么做的时候,处理器会产生一个页面错误 ,导致操作系统把所需要的数据从swap中加载回物理内存。

通过使用虚拟内存,可以使用的飞行中数据总量将扩展到物理内存大小和交换空间大小。 虽然这可以让系统同时运行更多的程序,但实际使用的内存数量永远不会超过可用的虚拟内存总量(即RAM +交换空间)

原则上,内核应该跟踪程序从中请求的内存量,并且一旦它的簿记告诉它所有的内存已经被分配 ,它应该拒绝更多内存的请求,尽pipe并不是所有内存都被使用过 。 大多数其他内核都这样做,所以他们没有OOM杀手(因为他们不需要)。

但是,系统调用程序从内核分配内存不会按字节分配内存, 它通过更大的块来分配它。 相比之下,大多数程序用于获取内存的实际实现( malloc() C库函数) 确实允许程序按字节分配内存。 这意味着大多数程序,当他们要求一些内存时,最终会以malloc()分配比实际需要更多的malloc() 。 另外,一个好的malloc()实现将使用一些启发式方法来保持越来越小的分配,因此内存碎片不会太差,但是这样做需要从内核请求更多的内存,从而加剧了这个问题。 由于这些和其他的影响,没有过度使用,将会有大量的内存被分配但是永远不会被使用。

过度使用的想法是,您可以安全地分配更多的内存,而不是虚拟内存的总量。 实质上,内核声称它允许一个分配,即使它知道它不能达到这个承诺,假设它不需要达到那些承诺的全部范围。 但是,可以过度使用的确切数量 – 分配 – 没有事情出错是无法预测的; 所以当内核检测到程序正在尝试使用所有分配的内存时,内核将不得不违背其承诺。 这是OOM杀手进来的地方。

这是不是一个好主意呢? 当系统内存不足时,会出现一些问题。 如果这是一些应用程序尝试分配更多内存的情况,但内核已经保留了所有内容,那么这个特定的应用程序可能会崩溃。 如果这恰好是你的X服务器,那你真是不值一提。 至less如果有一个OOM杀手,它可以决定哪个进程杀死,而不是坏的分配后的事情变坏; 和OOM杀手有一些逻辑,以避免杀死重要的进程,如您的X服务器…

然而,你更喜欢,有一些sysctl旋钮可以用来closuresovercommitting,你认为这是一个坏主意。