细说|Linux Out Of Memory机制
内容提要
OOM(Out Of Memory)机制是指当系统内存不足时,系统采取的应急措施。Linux内核会尝试回收可回收内存,如页缓存和延迟释放的空闲内存页。如果仍然不足,会触发OOM killer,杀掉占用内存最多的进程。OOM killer通过选择最坏的进程并调用oom_kill_process函数来实现。进程的最坏分数值是通过oom_badness函数计算的,包括进程使用的物理内存和oom_score_adj值。可以通过设置oom_score_adj值为-1000来禁止进程被OOM killer杀掉。
延伸解读
OOM触发路径:从缺页异常到进程终止
文章指出,进程申请虚拟内存时通常不会触发OOM,只有访问未映射的虚拟地址引发缺页异常,且内核在缺页处理中申请物理内存失败时,才会启动回收、swapping等缓解措施。若这些手段仍无法满足,内核才调用pagefault_out_of_memory()进入OOM killer流程。这一路径说明OOM并非由malloc直接导致,而是物理内存真正耗尽时的最后手段。
oom_badness评分机制:物理内存与建议值共同决定
OOM killer选择目标的核心是oom_badness()函数。它先排除init进程和内核进程等不可杀任务,再统计进程实际使用的物理内存、页表内存和swap占用,最后加上oom_score_adj换算后的调整值。分数最高的进程会被选中。这意味着占用物理内存越多、建议值越高的进程,越容易被终止。
保护关键进程:oom_score_adj设为-1000
文章提到,可通过/proc/{pid}/oom_score_adj设置进程的OOM建议值,范围-1000到1000。值越小,被杀机会越低;设为-1000时,内核会直接禁止OOM killer杀死该进程。例如对MySQL这类可能因被杀导致数据丢失的进程,可用echo -1000写入其oom_score_adj文件来提供保护。
OOM killer的定位:最后手段而非首选
文章强调,OOM killer是防止系统崩溃的最后一个手段,不到迫不得已不会触发。内核会优先回收页缓存和延迟释放的slab内存,再尝试swapping,只有这些措施都无效时才选择杀掉进程。因此,遇到进程被OOM终止时,应优先排查内存回收和交换机制是否已无法缓解压力。
Q&A
什么是Linux的OOM机制?
OOM机制是指当系统内存不足时,Linux内核采取的应急措施,主要通过回收可回收内存和触发OOM killer来释放内存。
Linux内核如何处理内存不足的情况?
内核首先尝试回收可回收内存,如页缓存和空闲内存页,如果仍然不足,则触发OOM killer,杀掉占用内存最多的进程。
OOM killer是如何选择要杀掉的进程的?
OOM killer通过计算每个进程的最坏分数值,选择占用内存最多的进程进行杀掉,使用的函数包括oom_badness和select_bad_process。
如何防止某个进程被OOM killer杀掉?
可以通过设置进程的oom_score_adj值为-1000来禁止该进程被OOM killer杀掉。
缺页异常是什么?
缺页异常是指当进程访问未映射的虚拟内存地址时,内核会申请新的物理内存页并进行映射。
swapping机制在内存不足时的作用是什么?
swapping机制将不常用的内存页写入交换区,以释放物理内存,从而缓解内存不足的情况。