linux中引起OOM Killer的原因及排查思路

2024-08-23 21:12

本文主要是介绍linux中引起OOM Killer的原因及排查思路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

OOM Killer(Out-Of-Memory Killer)的触发通常是由于Linux系统内存不足时,内核采取的一种极端保护措施。具体来说,OOM Killer触发的原因主要有以下几个方面:

一、触发OOM Killer原因

  • 系统内存耗尽

当系统物理内存(RAM)和交换空间(Swap)都被大量占用,无法满足新的内存分配请求时,OOM Killer会被触发。这通常发生在高负载的服务器上,当多个内存密集型应用同时运行时,系统内存很快就会被耗尽。

  • 内存分配失败

当某个进程尝试分配内存,但系统无法满足其请求时,内核会尝试通过回收内存(如页面回收、文件缓存回收等)来释放空间。如果回收的内存仍然不足,OOM Killer将被激活,以选择并终止某些进程来释放内存。

  • 内存泄漏

应用程序中的内存泄漏问题也可能导致OOM Killer的触发。内存泄漏是指程序在运行过程中,无法释放已经不再使用的内存空间,导致内存不断被占用,最终耗尽系统资源。

  • 特定进程的内存需求

某些进程可能因为内存需求过大,或者请求大块连续内存而触发OOM Killer。在32位系统中,由于地址空间的限制,大内存请求更容易导致问题。

  • 系统配置和策略

Linux内核提供了多种配置选项和策略,用于控制OOM Killer的行为。例如,可以通过调整/proc/sys/vm/oom_kill_allocating_task的值来决定是否杀死尝试分配内存的进程。此外,还可以通过设置进程的OOM得分(oom_score_adj)来调整其被OOM Killer选中的优先级。

  • 内核和硬件限制

在某些情况下,内核或硬件的限制也可能导致OOM Killer的触发。例如,在NUMA(Non-Uniform Memory Access)架构的系统中,节点间的内存分配限制可能导致OOM Killer的激活。

当OOM Killer被触发时,内核会计算每个进程的OOM得分,并选择得分最高的进程进行终止。OOM得分通常基于进程的内存使用量、优先级、类型等因素来计算。被终止的进程及其内存释放信息会被记录在系统日志中,以便管理员进行后续分析和处理。

二、排查思路

  1. 实时监控:通过系统监控工具(如tophtopfreevmstat等)查看当前系统内存使用情况,包括物理内存和交换空间。
  2. 检查系统日志:查看/var/log/messagesdmesg输出,寻找OOM Killer的相关信息,内核会在触发OOM Killer时记录相关信息,包括被杀掉的进程及其理由。
  3. 分析OOM Killer报告:当OOM Killer启动时,它会生成一个详细的报告,指出为何选择特定进程进行终止。可以通过这些信息来识别最可能的内存消耗大户。
  4. 定位消耗内存的进程:利用pspmapsmem等工具定位消耗内存最多的进程,并进一步分析其行为和资源需求。
  5. 检查程序日志和代码:如果确定是某个应用程序导致的OOM,应查看该程序的日志文件,了解其运行时的内存使用情况。同时,对代码进行审计,查找是否存在内存泄漏或其他不当内存管理。
  6. 启用内核OOME日志:在系统启动参数中加入vm.panic_on_oom=0vm.overcommit_memory=2(或适当调整内存过载策略),以便在发生OOM时让内核生成更详细的日志。
  7. 长期监控与趋势分析:使用像Prometheus + Grafana这样的监控系统长期收集内存使用数据并进行趋势分析,有助于提前发现潜在的内存使用增长问题。
  8. 优化资源配置:根据实际情况调整系统或容器的内存限制,优化程序以降低内存消耗,或者考虑增加物理内存和交换空间。
  9. 针对特定问题解决方案:例如,在图像处理或大数据场景中,采用合适的内存管理和缓存策略,避免一次性加载所有数据到内存中。对于Java应用,可通过调整JVM参数等方式优化内存管理。

三、优化建议

为了避免OOM Killer的触发,可以采取以下措施:

  • 优化内存使用:检查并优化应用程序的内存使用,避免内存泄漏和不必要的内存占用。
  • 增加内存资源:在系统允许的情况下,增加物理内存或交换空间的大小。
  • 调整OOM Killer策略:通过修改系统配置,调整OOM Killer的行为和优先级策略。
  • 监控和预警:使用系统监控工具实时监控系统内存使用情况,及时发现并处理内存不足的问题。

四、实例分析

1、ls触发OMM

Aug 17 03:12:59 Hygonrbej01 kernel: [159440.49643] ls invoked oom-killer: gfp_mask=0x6040c0(GFP_KERNEL|__GFP_COMP), nodemask=(null), order=3, oom_score_adj=0
Aug 17 03:12:59 Hygonrbej01 kernel: [159440.49646] ls cpuset=/ mems_allowed=0
Aug 17 03:12:59 Hygonrbej01 kernel: [159440.49652] CPU: 0 PID: 389525 Comm: ls Kdump: loaded Tainted: GOE  4.19.90-23.26.v2101.ky10.x86_64 #1

这段日志显示了Linux系统中的一个内存不足(OOM, Out of Memory)事件,具体是由ls命令触发的。ls命令是一个常用的列出目录内容的命令,但在某些情况下,如果它试图读取或处理大量文件,并且系统内存已经接近耗尽,就可能会触发OOM Killer。不过,在这个特定的例子中,ls命令本身作为OOM Killer的受害者似乎有些不寻常,因为ls通常不会消耗大量内存。这可能是由于其他因素导致的,比如系统内存已经极度紧张,或者ls命令在处理某些特殊文件或目录时遇到了问题。

以下是日志中关键信息的解释:

  • OOM Killer被调用:日志中的ls invoked oom-killer表明ls进程是触发OOM Killer的“罪魁祸首”。但请注意,这并不一定意味着ls是内存泄漏或过度使用内存的源头;它可能只是在系统内存已经严重不足时尝试分配内存的众多进程之一。

  • 内存分配请求gfp_mask=0x6040c0(GFP_KERNEL|__GFP_COMP)表示这是一个内核内存分配请求,使用了GFP_KERNEL__GFP_COMP标志。GFP_KERNEL是内核分配内存时最常用的标志,表示可以等待内存释放;__GFP_COMP可能是一个与内存压缩相关的标志,但在较新的Linux版本中可能不再使用或已更改含义。

  • 节点和CPU信息nodemask=(null)表明没有特定的NUMA节点偏好;CPU: 0表明OOM Killer的日志是在CPU 0上记录的。

  • 进程信息PID: 389525 Comm: ls显示了被OOM Killer选中的进程ID(PID)和命令名(Comm)。

  • 系统信息:包括硬件名称、BIOS版本等信息,这些信息对于分析系统环境和可能的问题源很有帮助。

  • 调用栈Call Trace部分显示了导致OOM Killer被触发的函数调用栈。这有助于开发者或系统管理员了解在内存分配失败时,系统是如何处理并最终决定杀死某个进程的。

  • 内存信息(Mem-Info):这部分提供了关于系统内存使用情况的详细统计,包括活跃和非活跃的内存、slab内存、映射的内存、共享内存等。这些信息对于诊断内存问题非常有用。

2、Java进程被kill9

Aug 17 03:12:59 Hygonrbej01 kernel: [159440.49894] Out of memory: Kill process 3067998 (java) score 244 or sacrifice child
Aug 17 03:12:59 Hygonrbej01 kernel: [159440.50254] Killed process 367998 (java) total-vm:12717748kB, anon-rss:3581268kB, file-rss:3936kB, shmem-rss:20kB
Aug 17 03:12:59 Hygonrbej01 kernel: [159440.19186] oom_reaper: reaped process 3067998 (java), now anon-rss:0kB, file-rss:0kB, shmem-rss:20kB
Aug 17 03:12:59 Hygonrbej01 systemd[1]: bes.service: Main process exited, code=killed, status=9/KILL
Aug 17 03:12:59 Hygonrbej01 systemd[1]: bes.service: Failed with result 'signal'.

这段日志记录了几个关键事件,主要涉及系统内存管理、服务失败。下面是对这些事件的详细解释:

  1. 内存不足(OOM Killer 触发)
    • Out of memory: Kill process 3067998 (java) score 244 or sacrifice child:这表示系统遇到了内存不足(Out of Memory, OOM)的情况,OOM Killer 被激活以杀死一些进程以释放内存。它选择了进程ID为3067998的Java进程作为牺牲品,因为这个进程的OOM分数(score)最高,为244。OOM分数是基于进程占用的内存量、优先级等因素计算得出的。
  2. Java进程被杀死
    • Killed process 3067998 (java) total-vm:12717748kB, anon-rss:3581268kB, file-rss:3936kB, shmem-rss:20kB:这进一步确认了Java进程(PID 3067998)已被杀死。该进程占用的总虚拟内存(total-vm)为12,717,748kB,匿名可回收内存(anon-rss)为3,581,268kB,文件映射内存(file-rss)为3,936kB,共享内存(shmem-rss)为20kB。
  3. OOM Reaper 清理
    • oom_reaper: reaped process 3067998 (java), now anon-rss:0kB, file-rss:0kB, shmem-rss:20kB:OOM Reaper 是一个内核线程,负责清理OOM Killer杀死的进程留下的资源。这里显示Java进程的匿名可回收内存和文件映射内存已被清零,但共享内存(可能是因为它不是由该进程独占的)保持不变。
  4. 服务失败
    • systemd[1]: bes.service: Main process exited, code=killed, status=9/KILLsystemd[1]: bes.service: Failed with result 'signal':这表明一个名为bes.service的服务的主进程被信号(这里是KILL信号)杀死,导致服务失败。这很可能与前面提到的Java进程被杀有关,如果该Java进程是该服务的一部分。

这篇关于linux中引起OOM Killer的原因及排查思路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1100509

相关文章

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u

linux解压缩 xxx.jar文件进行内部操作过程

《linux解压缩xxx.jar文件进行内部操作过程》:本文主要介绍linux解压缩xxx.jar文件进行内部操作,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、解压文件二、压缩文件总结一、解压文件1、把 xxx.jar 文件放在服务器上,并进入当前目录#

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

在Linux中改变echo输出颜色的实现方法

《在Linux中改变echo输出颜色的实现方法》在Linux系统的命令行环境下,为了使输出信息更加清晰、突出,便于用户快速识别和区分不同类型的信息,常常需要改变echo命令的输出颜色,所以本文给大家介... 目python录在linux中改变echo输出颜色的方法技术背景实现步骤使用ANSI转义码使用tpu

linux hostname设置全过程

《linuxhostname设置全过程》:本文主要介绍linuxhostname设置全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录查询hostname设置步骤其它相关点hostid/etc/hostsEDChina编程A工具license破解注意事项总结以RHE

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存