1、OOM Killer

1.1、OOM Killer定义

OOM(Out Of Memory) Killer作为linux系统中守护进程,主要在系统内存严重不足时开始工作。出现这种情况是因为服务器上的进程正在消耗大量内存,而系统需要更多的内存分配给其他进程。

当一个进程启动时会向内核请求一块内存,申请的内存通常是很大一块,进程也不需要立即或永远不需要使用如此大的内存(这与平时游戏启动类似,游戏可能占据20g,启动进程可能申请22g,但系统内存可能就8g,它不会也不可能分配22g,但这并不会影响游戏的启动)。 这是因为内核意识到进程会过度申请内存,内核也会过度为进程分配内存,但实际分配时并不会立马满足进程所申请的大小。

一般情况下这并不会有什么问题。但如果有足够多的进程开始使用它们申请的所有内存块,那么系统将没有足够的物理内存分配给这些进程。这种情况下Linux 内核采用的解决方案是调用 OOM Killer来检查所有正在运行的进程并杀死其中一个或多个以释放系统内存来保证系统正常运行。

1.2、OOM Killer选择进程过程

当系统内存分配失败时就会调用out_of_memory()函数,该函数中调用了select_bad_process()函数,select_bad_process()通过badness()函数获取目标进程对应的分数,而最终分数最高的进程会被OOM Killer清理,badness()函数内部有一套规则来选择目标进程:
1、内核为自己保留运行所需最小内存并尝试回收大量的存;
2、优先剔除内存占用高的进程,尝试杀死最少数量的进程;
3、一些算法可以调整进程被终止的优先级;

以上所有检查项执行完毕,OOM Killer将为每个进程设置oom_score,而OOM Killer最终终止进程所使用的值为oom_score乘上对应进程内存使用大小,与特权用户关联的进程一般具有较低分值,其被OOM Killer终止的机会较小。

#获取目标进程的pid
$ ps -ef | grep elasticsearch
elastic+ 13193     1  3 3月16 ?       05:08:05 /bin/java -Xms8g -Xmx8g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+AlwaysPreTouch -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:-OmitStackTraceInFastThrow -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Djava.io.tmpdir=/tmp/elasticsearch.37r3k1y7 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/lib/elasticsearch -XX:ErrorFile=/var/log/elasticsearch/hs_err_pid%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime -Xloggc:/var/log/elasticsearch/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=32 -XX:GCLogFileSize=64m -Des.path.home=/usr/share/elasticsearch -Des.path.conf=/etc/elasticsearch -Des.distribution.flavor=default -Des.distribution.type=rpm -cp /usr/share/elasticsearch/lib/* org.elasticsearch.bootstrap.Elasticsearch -p /var/run/elasticsearch/elasticsearch.pid --quiet
elastic+ 13280 13193  0 3月16 ?       00:00:00 /usr/share/elasticsearch/modules/x-pack-ml/platform/linux-x86_64/bin/controller
#查看目标进程的oom_score
$ cat /proc/13193/oom_score

若用户真不想自己的进程被OOM Killer终止,内核还提供了另一个参数oom_score_adj,用户可以为对应进程添加一个很大的负值,以降低OOM Killer在计算分值时的分数;

#调整目标进程的初始值
$ echo -100 > /proc/13193/oom_score_adj

要想在该进程启动时自动初始化数值,可通过OOMScoreAdjust配置项设置:

$ systemctl status elasticsearch
● elasticsearch.service - ElasticsearchLoaded: loaded (/usr/lib/systemd/system/elasticsearch.service; enabled; vendor preset: disabled)Active: active (running) since 三 2022-03-16 19:22:08 CST; 5 days agoDocs: http://www.elastic.coMain PID: 13193 (java)CGroup: /system.slice/elasticsearch.service├─13193 /bin/java -Xms8g -Xmx8g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+...└─13280 /usr/share/elasticsearch/modules/x-pack-ml/platform/linux-x86_64/bin/controller
$ vim /usr/lib/systemd/system/elasticsearch.service[Service]
Restart=on-failure
RestartSec=1
RuntimeDirectory=elasticsearch
PrivateTmp=true
Environment=ES_HOME=/usr/share/elasticsearch
Environment=ES_PATH_CONF=/etc/elasticsearch
Environment=PID_DIR=/var/run/elasticsearch
EnvironmentFile=-/etc/sysconfig/elasticsearch
#配置elasticsearch进程oom_score初始值
OOMScoreAdjust=-1000

1.3、OOM Killer终止链路

当OOM Killer选择一个或多个进程时将会调用oom_kill_task()函数,该函数负责向进程发送kill信号。在内存不足时oom_kill()函数将会调用此函数,它将向进程发送sigkill信号并生成内核日志消息:

kernel: Call Trace:
kernel: [<ffffffffaf779262>] dump_stack+0x19/0x1b
kernel: [<ffffffffaf773c04>] dump_header+0x90/0x229
kernel: [<ffffffffaf1047e2>] ? ktime_get_ts64+0x52/0xf0
kernel: [<ffffffffaf1bfd74>] oom_kill_process+0x254/0x3e0
kernel: [<ffffffffaf1314d1>] ? cpuset_mems_allowed_intersects+0x21/0x30
kernel: [<ffffffffaf1bf81d>] ? oom_unkillable_task+0xcd/0x120
kernel: [<ffffffffaf1bf8c6>] ? find_lock_task_mm+0x56/0xc0
kernel: [<ffffffffaf1c05c6>] out_of_memory+0x4b6/0x4f0
kernel: [<ffffffffaf77471c>] __alloc_pages_slowpath+0x5d6/0x724
kernel: [<ffffffffaf1c6b84>] __alloc_pages_nodemask+0x404/0x420
kernel: [<ffffffffaf214c68>] alloc_pages_current+0x98/0x110
kernel: [<ffffffffaf1bbc77>] __page_cache_alloc+0x97/0xb0
kernel: [<ffffffffaf1be838>] filemap_fault+0x298/0x490
kernel: [<ffffffffc048e55e>] __xfs_filemap_fault+0x7e/0x1d0 [xfs]
kernel: [<ffffffffc048e75c>] xfs_filemap_fault+0x2c/0x30 [xfs]
kernel: [<ffffffffaf1ea29a>] __do_fault.isra.61+0x8a/0x100
kernel: [<ffffffffaf1ea84c>] do_read_fault.isra.63+0x4c/0x1b0
kernel: [<ffffffffaf1ef2fa>] handle_pte_fault+0x22a/0xe20
kernel: [<ffffffffaf214c68>] ? alloc_pages_current+0x98/0x110
kernel: [<ffffffffaf1f200d>] handle_mm_fault+0x39d/0x9b0
kernel: [<ffffffffaf786633>] __do_page_fault+0x213/0x500
kernel: [<ffffffffaf786955>] do_page_fault+0x35/0x90
kernel: [<ffffffffaf782768>] page_fault+0x28/0x30kernel: Out of memory: Kill process 13193 (java) score 620 or sacrifice child
kernel: Killed process 13193 (java), UID 499, total-vm:368666832kB, anon-rss:15038044kB, file-rss:0kB, shmem-rss:0kB

1.4、OOM Killer启用或禁用

Linux提供了一种启用和禁用 OOM Killer 的方法(不建议),可以通过编辑panic_on_oom 变量来启用或禁用OOM Killer,用户可随时查看/proc中的值。

$ cat /proc/sys/vm/panic_on_oom
0

用户将该值设置为 0 时意味着发生内存不足错误时引起内核的恐慌机制,反之则会触发:

$ echo 0 > /proc/sys/vm/panic_on_oom
$ echo 1 > /proc/sys/vm/panic_on_oom

除了启用和禁用之外,OOM Killer关于内存还有其他配置。正如前面所说,Linux可以通过分配内存来过度使用内存,这可以通过Linux内核参数vm.overcommit_memory来控制:

0: 启发式策略,内核将决定是否过度使用,这是大多数Linux版本的默认值。
1: 永远允许overcommit,这是一个有风险的设置,因为内核总是将内存过度分配给进程。 这可能导致内核内存不足,因为进程很有可能最终会使用向内核申请的内存。
2: 永远禁止overcommit,这意味着内核不应过度使用大于 overcommit_ratio的内存,overcommit_ratio是另一个内核参数,用户可以指定内核内存可过度使用百分比。如果没有多余的内存空间用于overcommit则内存分配失败,overcommit申请被拒绝。

可以影响OOM Killer行为的第二件事是swappiness配置,该配置用于将页面从物理内存换出到交换空间、从交换空间换入到物理内存空间及从页面缓存中删除页面等,可通过一下命令查看及配置:

# 不同版本或系统该值会存在差异
$ cat  /proc/sys/vm/swappiness
30

Swappiness可以设置0到100之间的值,较低的值将尽可能避免使内核交换,而较高的值意味着内核将尝试更积极地使用交换空间。所以该值越大OOM Killer终止进程的机会越小,但它会因为I/O而影响进程处理效率,部署Elasticsearch一般建议关闭交换空间,即对应值为0

#oom相关配置项,省略部分
$ ls -lrt /proc/sys/vm/
oom_dump_tasks
oom_kill_allocating_task
overcommit_kbytes
overcommit_memory
overcommit_ratio
panic_on_oom
swappiness

上面列出的标准意味着OOM Killer在选择终止的过程时,将优先选择那些内存占用高、有大量子进程且不为系统进程的进程。

2、总结

我们不必被OOM Killer这个名字所迷惑,该进程能够保证系统在内存分配严重不足时保证系统仍正常运行,它会终止造成内存不足这种情况的负最大责任的进程。若用户希望用户进程免遭OOM Killer终止,那建议将vm.overcommit_memory值设置为2,虽然该配置无法保证百分之百避免被终止,但会降低被终止的概率。

Linux内存清道夫--OOM Killer相关推荐

  1. linux内核中内存耗尽OOM killer

    当内存严重不足时,页分配器在多次尝试直接回收失败后,就会调用内存耗尽OOM killer,选择杀死进程,释放内存. 先看一段oom 输出的错误 [ 7981.765805] kthreadd invo ...

  2. 理解和配置 Linux 下的 OOM Killer

    原文:http://www.vpsee.com/2013/10/how-to-configure-the-linux-oom-killer/ 最近有位 VPS 客户抱怨 MySQL 无缘无故挂掉,还有 ...

  3. Linux 的 Out-of-Memory (OOM) Killer

    同事在 Linux 服务器上遇到点小问题,我也上去折腾半天.这还是第一次注意到 Linux 这个多年来就存在的特性:OOM Killer .说白了 OOM Killer 就是一层保护机制,用于避免 L ...

  4. (转载)Linux OOM Killer个人总结

    Linux下面有个特性叫OOM killer(Out Of Memory killer),这个东西会在系统内存耗尽的情况下跳出来,选择性的干掉一些进程以求释放一些内存.典型的情况是:某天机器突然登不上 ...

  5. Linux OOM Killer

    如何配置 Linux 内存不足终止程序 本文介绍了 Linux 内存不足 (OOM) 终止程序以及如何查明该程序终止特定进程的原因.文中还介绍了配置 OOM 终止程序的方法,以便更好地适应各种不同环境 ...

  6. Java内存溢出(OOM)异常完全指南

    原文:http://luecsc.blog.51cto.com/2219432/1948800 这也许是目前最为完整的Java OOM异常的解决指南. 1.Java.lang.OutOfMemoryE ...

  7. linux内核oom,linux OOM killer分析

    基本概念 Linux 内核有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了防止内存耗尽而内核会把该进程杀 ...

  8. linux进程莫名其妙被kill,Linux进程突然被杀掉(OOM killer),查看系统日志

    Linux进程被杀掉(OOM killer),查看系统日志 基本概念: Linux 内核有个机制叫OOM killer(Out Of Memory killer),该机制会监控那些占用内存过大,尤其是 ...

  9. (转载)Linux Out-of-Memory(OOM) Killer

    Linux有一个特性:OOM Killer,一个保护机制,用于避免在内存不足的时候不至于出现严重问题,把一些无关的进程优先杀掉,即在内存严重不足时,系统为了继续运转,内核会挑选一个进程,将其杀掉,以释 ...

最新文章

  1. 3G突破必须打破漫游费的限制
  2. linux内核驱动识别过程,转载_ARM-Linux内核驱动加载过程思路
  3. 【PHP】函数的引用返回
  4. 关于小程序·云开发峰会,你想get的干货全在这了!
  5. springboot2——MyBatis入门
  6. Metasploit渗透测试框架
  7. 【eevee.cc】文章归档
  8. 职业培训学校计算机培训计划,职业技能学校关于计算机应用一级MS-Office培训开班计划.doc...
  9. VS2013 百度云资源以及密钥
  10. 英语单词-每天10个
  11. 创业和工作的心态问题
  12. 实战:用 C 语言实现操作系统
  13. ios 获取沙盒文件名_iOS之沙盒路径
  14. JSP导入导出Excel功能
  15. GitChat,一个记录技术和躺着赚零花钱的免费平台
  16. php cli python,PHP MVC框架 CodeIgniter CLI模式简介
  17. 用计算机弹精灵宝可梦音乐,《精灵宝可梦》图鉴402:可以演奏出优美音乐的精灵——音箱蟀...
  18. asm cli/sti 指令
  19. Nacos配置中心实战,盘古开发框架标配组件
  20. Java汉字转拼音(全拼、首字母拼)

热门文章

  1. 计算机网络地址分类与案例详解
  2. 活动招募 HUAWEI HiAI公开课·北京站-如何在4小时把你的APP变身AI应用
  3. 2017北京国际面料、辅料及纱线(春夏)展览会 2017北京国际服装贴牌加工(OEM/ODM)展览会会刊(参展商名录)
  4. Navicat中查看MySQL通用查询日志的方法
  5. linux tcl 循环foreach,tcl foreach用法
  6. 简易计时器编写 V2.0
  7. Python中fileinput库
  8. 多材料线弹性固体的应力分析
  9. Android性能优化之布局优化篇
  10. RPKM、FPKM、TPM