当进程发现没有内存可用时如何处理这种情况?

当进程发现没有内存可用时如何处理这种情况?

当特定进程发现没有内存可用时会发生什么?

该进程会杀死/重新启动另一个进程来继续他们的任务吗?

或者在这种情况下(需要更多内存的进程)会做什么?

如果可能的话,任何人都可以提供与此相关的良好链接吗?

答案1

在某些请求分页虚拟内存系统上,操作系统拒绝分配匿名页面(即包含没有文件系统源的数据的页面,例如运行时数据、程序堆栈等),除非有足够的交换空间来交换这些页面以便释放物理内存。这种严格计算的优点是保证每个进程都能访问它们分配的尽可能多的虚拟内存,但这也意味着可用的虚拟内存量本质上受到交换空间大小的限制。

Linux 内核中的内存统计尝试通过跟踪进程实际使用的内存量来补偿那些倾向于分配比其使用更多内存的程序,并且过度承诺虚拟内存量。换句话说,内核分配的虚拟内存量可能超过系统上物理内存和交换空间的总和。实际上,这意味着内存分配malloc()永远不会失败。虽然这可以更好地利用物理内存和交换空间,但缺点是当使用的内存量超过可用的物理内存和交换空间量时,内核必须以某种方式释放内存资源以满足内存分配承诺。

用于回收内存以填充复用的内核机制称为内存不足杀手(OOM 杀手)。通常,该机制将开始杀死占用内存的“流氓”进程,为其他进程释放内存。 OOM-killer 和内存核算算法的行为可以通过sysctl设置或/proc/sys/vm。如果vm.panic_on_oom设置非零,当系统内存不足时,内核将出现恐慌。

OOM-killer 使用的启发式可以通过vm.oom_kill_allocating_task设置进行修改。默认情况下,OOM-killer 将扫描任务列表并选择一个占用大量内存的恶意任务来杀死。 OOM-killer 还可以配置为终止触发内存不足情况的任务。

可以通过设置来调整内核内存统计算法vm.overcommit_memory。默认是在过度使用之前执行一些弱启发式检查,但内存计费算法也可以设置为严格模式,其中虚拟地址空间限制由vm.overcommit_ratio根据以下公式设置的值确定:

    virtual memory = (swap + physical memory * (overcommit_ratio / 100))

当使用严格的内存统计时,内核将不再分配匿名页面,除非它有足够的可用物理内存或交换空间来存储页面。这意味着该系统必须配置了足够的交换空间。除非有足够的物理内存或交换空间来满足内存承诺,否则调用可能malloc()会失败。在这些情况下,由程序本身决定适当的行动方案。有些人可能会放弃并彻底失败,但他们也可能会退回到速度较慢但内存效率更高的算法来执行他们需要内存分配的操作。

答案2

这取决于程序配置的用途。简单的程序只是打印一条错误消息,然后在无法分配足够的内存时终止。有些程序尝试自行释放一些内存并重试。有些程序在退出前会执行一些紧急状态保存。有些程序会以某种方式继续运行,并且在没有额外内存的情况下继续运行,也许是在通知用户某些命令无法执行之后。

虽然原则上一个进程可以杀死另一个进程,但这将是一种极其奇怪的行为。该进程无法知道要杀死哪些进程,也无法保证它能够获取它们的内存。

如果内核检测到内存不足内核可能会基于复杂的启发法(例如“不杀死sshd”)而不是由应用程序杀死某些进程。

相关内容