linux内核中内存耗尽OOM killer
Posted 为了维护世界和平_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux内核中内存耗尽OOM killer相关的知识,希望对你有一定的参考价值。
当内存严重不足时,页分配器在多次尝试直接回收失败后,就会调用内存耗尽OOM killer,选择杀死进程,释放内存。
先看一段oom 输出的错误
[ 7981.765805] kthreadd invoked oom-killer: gfp_mask=0x2dc2(GFP_KERNEL|__GFP_HIGHMEM|__GFP_NOWARN|__GFP_ZERO), order=0, oom_score_adj=0
[ 7981.777742] CPU: 3 PID: 2 Comm: kthreadd Tainted: G O 5.4.0-xilinx-v2020.1 #1
[ 7981.786164] Hardware name: xlnx,zynqmp (DT)
[ 7981.790329] Call trace:
[ 7981.792767] dump_backtrace+0x0/0x140
[ 7981.796415] show_stack+0x14/0x20
[ 7981.799717] dump_stack+0xac/0xd0
...
[ 7982.331629] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/,task=net_process,pid=1275,uid=0
[ 7982.344516] Out of memory: Killed process 1275 (net_process) total-vm:4113316kB, anon-rss:3888320kB, file-rss:36kB, shmem-rss:2052kB, UID:0 pgtables:7852032kB oom_score_adj:0
[ 7982.974247] oom_reaper: reaped process 1275 (net_process), now anon-rss:0kB, file-rss:0kB, shmem-rss:2052kB
在应用程序开发时会出现内存泄露,如上述所示,杀死net_process进程信息。在内核中是如何处理的呢?
内存耗尽可配置的参数如下:
/proc/sys/vm/oom_kill_allocating_task
是否允许杀死正在申请分配内存并触发内存耗尽的进程,避免扫描进程链表选择进程。
0表示禁止,非零表示允许
/proc/sys/vm/oom_dump_tasks
是否允许内存耗尽杀死进程的时候,是否打印所有用户进程的内存使用信息,
0表示禁止,非零表示允许
/proc/sys/vm/panic_on_oom
是否允许在内存耗尽的时候内核panic,重启系统。
0:表示禁止内核恐慌,1 表示允许内核恐慌;2强制执行内核恐慌
杀死进程的计算方法
给进程计算分数(badness score),选择分数最高的进程。分数范围0~1000,0 表示不杀死,1000表示总是杀死。
- 用户可以在/proc/<pid>/oom_score_adj 为进程设置分数值范围[-1000,1000]。值越大导致杀死时的分数越高。
- 查看进程分数/proc/<pid>/oom_socre
技术原理
内存耗尽杀手分为全局的内存耗尽杀手和内存控制组的内存耗尽杀手。
- 内存控制组的内存耗尽杀手指内存控制组的内存使用量超过硬限制的时候,内存控制组选择进程杀死。
- 全局的内存耗尽杀手是指内存严重不足的时候,从整个系统选择进程杀死。
oom_kill_process执行过程
- 如果被选中的进程有子进程,那么从所有子进程中选择badness score最高的子进程代替父进程牺牲,试图使丢失的工作量最小化。(在多进程的服务端场景)
- 向被选中的进程发送杀死信号SIGKILL
参考链接
https://course.0voice.com/v1/course/intro?courseId=2&agentId=0
以上是关于linux内核中内存耗尽OOM killer的主要内容,如果未能解决你的问题,请参考以下文章