如何理解Linux内核参数overcommit_memory和OOM killer

如何理解Linux内核参数overcommit_memory和OOM killer,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

什么是Linux Overcommit和OOM

overcommit_memory是一个内核对内存分配的一种策略,它有三个可选值:0、1、2。

0. 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,

并把错误返回给应用进程。

1. 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。

2. 表示内核允许分配超过所有物理内存和交换空间总和的内存。

Linux对大部分申请内存的请求都回复"yes",以便能跑更多更大的程序。因为申请内存后,并不会马上使用内存。

这种技术叫做 Overcommit。

当linux发现内存不足时,会发生OOM killer(OOM=out-of-memory)。它会选择杀死一些进程

(用户态进程,不是内核线程),以便释放内存。

例如Linux下发现有如下报错信息,则说明系统发生了OOM killer

# dmesg | grep redis | grep "oom-killer"

redis-server invoked oom-killer: gfp_mask=0x280da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x200da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x200da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x200da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x280da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x200da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x200da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0xd0, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x280da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x280da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0xd0, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x280da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0xd0, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0xd0, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0xd0, order=0, oom_adj=0, oom_score_adj=0

redis-server invoked oom-killer: gfp_mask=0x280da, order=0, oom_adj=0, oom_score_adj=0

当oom-killer发生时,linux会选择杀死该进程,例如:

Out of memory: Kill process 21809 (redis-server) score 951 or sacrifice child

Killed process 21809, UID 0, (redis-server) total-vm:33466920kB, anon-rss:32324096kB, file-rss:100kB

具体杀死哪个进程取决于选择进程的函数,选择进程的函数是oom_badness函数(在mm/oom_kill.c中),该函数

会计算每个进程的点数(0~1000)。

点数越高,这个进程越有可能被杀死。每个进程的点数跟oom_score_adj有关,而且 oom_score_adj可以被

设置(-1000最低,1000最高)。

理解memory overcommit的关键:commit(或overcommit)针对的是内存申请,内存申请不等于内存分配,内存

只在实际用到的时候才分配。

备注:

如何修改Linux vm.overcommit_memory的值,可用的方法有以下三种:

1).以root身份登录Linux,编辑/etc/sysctl.conf ,改vm.overcommit_memory=1,然后sysctl -p使配置文件生效

2).sysctl vm.overcommit_memory=1

3).echo 1 > /proc/sys/vm/overcommit_memory

看完上述内容,你们掌握如何理解Linux内核参数overcommit_memory和OOM killer的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/199293.html

(0)
上一篇 2021年11月20日
下一篇 2021年11月20日

相关推荐

发表回复

登录后才能评论