当前位置: 首页 > news >正文

Linux OOM Killer详解

Linux OOM Killer详解

      • 一、概述
      • 二、OOM Killer的技术原理
        • 1. 内存区域划分
        • 2. 内存耗尽与OOM Killer触发
        • 3. 选择被杀进程的策略
        • 4. 内存回收机制
        • 5. 内存分配策略
      • 三、OOM Killer的工作机制
        • 1. 内存压力监测
        • 2. 触发条件
        • 3. 选择被杀进程
        • 4. 终止进程
      • 四、实际场景举例
        • 场景一:系统内存耗尽时的OOM Killer触发
        • 场景二:LowMem耗尽导致OOM Killer触发
        • 场景三:特定进程优先被杀
        • 场景四:保护关键进程
      • 五、优化和解决方案
        • 1. 升级到64位系统
        • 2. 使用hugemem内核
        • 3. 调整内核参数
        • 4. 关闭OOM Killer(风险较高)
        • 5. 配置内核参数以自动重启系统
      • 六、总结

一、概述

在Linux操作系统中,内存管理至关重要。当系统内存耗尽时,如果不采取措施,会导致系统崩溃。为了解决这个问题,Linux内核引入了一种保护机制——OOM Killer(Out-Of-Memory Killer)。当系统内存耗尽时,OOM Killer会选择并终止一些进程,以释放内存,确保系统继续运行。本博客将详细介绍OOM Killer的技术原理、工作机制,并通过实际场景举例说明其应用。

二、OOM Killer的技术原理

1. 内存区域划分

在32位CPU架构下,Linux内核将物理内存划分为三个区域:

  1. DMA区域:0x00000000 - 0x00999999(0 - 16 MB)
  2. LowMem区域:0x01000000 - 0x037999999(16 - 896 MB)
  3. HighMem区域:0x038000000 - <硬件特定>

LowMem区域(也叫Normal Zone)一共880 MB,是内核直接映射的物理地址范围。这意味着,内核需要直接使用的内存必须分配在LowMem区域内。HighMem区域用于用户空间进程的数据存储,但内核访问这部分内存需要进行额外的地址映射。

在64位系统中,所有物理内存都可以被直接映射,因此LowMem和HighMem的划分问题不再存在。然而,在32位系统中,由于LowMem区域有限,内存密集型应用很容易导致LowMem耗尽,触发OOM Killer。

2. 内存耗尽与OOM Killer触发

当系统内存耗尽时,内核会尝试回收可用内存。如果内存仍然不足,内核将触发OOM Killer来选择并终止进程,以释放内存。OOM Killer的主要目的是确保系统不至于完全崩溃,而是通过释放内存来维持运行。

3. 选择被杀进程的策略

OOM Killer选择被杀进程的策略涉及多个因素,包括:

  • 进程的OOM得分:每个进程都有一个OOM得分(oom_score),表示该进程被杀的优先级。OOM得分越高,进程越有可能被杀。
  • 进程的内存使用量:使用内存越多的进程,更有可能被选中。
  • 进程的优先级调整:可以通过调整进程的oom_adj或oom_score_adj值来改变其OOM得分,从而影响被杀优先级。
4. 内存回收机制

Linux内核通过多种机制进行内存回收,包括:

  • 页面回收:回收不常用的页面,将其写回磁盘或释放。
  • 文件缓存回收:回收文件系统缓存,释放更多内存给应用程序使用。
  • 交换空间:将内存页交换到磁盘上的交换空间(swap),以释放物理内存。
5. 内存分配策略

Linux内核使用多种内存分配策略,包括伙伴系统、slab分配器等,以提高内存分配和回收的效率。当内存不足时,内核会使用这些策略来尽可能满足内存分配请求。

三、OOM Killer的工作机制

1. 内存压力监测

内核会持续监测系统的内存使用情况,特别是LowMem区域。当LowMem区域的可用内存达到一个临界点时,内核会认为系统处于内存压力状态,并开始采取措施。

2. 触发条件

OOM Killer的触发条件主要有两个:

  • LowMem耗尽:当LowMem区域的可用内存不足,无法满足内核的内存分配请求时,OOM Killer会被触发。
  • 系统内存耗尽:当系统整体内存耗尽,无法通过正常的内存回收机制释放足够的内存时,OOM Killer会被触发。
3. 选择被杀进程

当OOM Killer被触发时,内核会计算每个进程的OOM得分,并选择得分最高的进程进行终止。计算OOM得分的因素包括:

  • 内存使用量:使用内存越多的进程,得分越高。
  • 进程优先级:通过oom_adj或oom_score_adj调整的优先级。
  • 进程类型:系统关键进程(如init进程)通常不会被选择。
4. 终止进程

内核会向选择的进程发送SIGKILL信号,强制终止该进程,并释放其占用的内存。被终止的进程及其内存释放信息会记录在系统日志中。

四、实际场景举例

场景一:系统内存耗尽时的OOM Killer触发

假设有一个高负载的服务器,运行多个内存密集型应用。当所有应用同时消耗大量内存时,系统内存耗尽。此时,OOM Killer触发,并在/var/log/messages日志文件中记录如下信息:

Out of Memory: Killed process 1234 (myapp) total-vm:512000kB, anon-rss:256000kB, file-rss:128000kB, shmem-rss:64000kB

此信息表明进程myapp(PID为1234)被OOM Killer终止,以释放512 MB的虚拟内存。

场景二:LowMem耗尽导致OOM Killer触发

在32位系统中,LowMem区域是内核直接访问的内存。如果LowMem耗尽,即使HighMem还有可用内存,OOM Killer也会触发。例如,运行以下命令查看LowMem和HighMem的状态:

egrep 'High|Low' /proc/meminfo

输出结果:

HighTotal: 5111780 kB
HighFree: 1172 kB
LowTotal: 795688 kB
LowFree: 16788 kB

此时,LowMem只有16 MB可用内存,而HighMem还有1.1 GB。若内核需要分配更多LowMem,而没有足够空间,OOM Killer将会触发,终止一些进程以释放LowMem。

场景三:特定进程优先被杀

某些应用程序的内存使用非常高,但不是系统关键进程。在内存紧张时,可以通过调整oom_score_adj值,提高这些进程的OOM得分,使其优先被杀。例如,将一个非关键进程的oom_score_adj值设置为10:

echo 10 > /proc/[pid]/oom_score_adj

当系统内存耗尽时,这个进程将优先被OOM Killer终止。

场景四:保护关键进程

对于一些关键进程,可以通过设置oom_score_adj值为-17,使其在内存紧张时不会被OOM Killer杀死。例如:

echo -17 > /proc/[pid]/oom_score_adj

这样,即使系统内存耗尽,该进程也不会被终止。

五、优化和解决方案

1. 升级到64位系统

最有效的解决方案是升级到64位系统。在64位系统中,所有内存都属于LowMem,可以避免32位系统中LowMem耗尽的问题。如果升级64位系统不可行,可以尝试以下方法:

2. 使用hugemem内核

hugemem内核通过不同的方式划分LowMem和HighMem,并提供更多LowMem到HighMem的映射。安装hugemem内核后,系统会有更多的LowMem可用。

安装hugemem内核:

yum install kernel-hugemem
reboot
3. 调整内核参数

通过调整/proc/sys/vm/lower_zone_protection的值,增加LowMem的保护级别。该参数从2.6.x内核开始可用,可以通过以下方式设置:

echo "250" > /proc/sys/vm/lower_zone_protection

在/etc/sysctl.conf中添加设置,以便启动时生效:

vm.lower_zone_protection = 250
4. 关闭OOM Killer(风险较高)

关闭OOM Killer可以避免进程被自动终止,但可能导致系统挂起,因此需谨慎使用:

echo "0" > /proc/sys/vm/oom-kill

查看当前OOM Killer状态:

cat /proc/sys/vm/oom-kill
5. 配置内核参数以自动重启系统

在/etc/sysctl.conf中添加以下配置,使系统在Out of Memory后自动重启:

vm.panic_on_oom = 1
kernel.panic = 10

执行以下命令应用配置:

sysctl -p
  1. 调整进程的oom_score_adj值

可以通过调整进程的oom_score_adj值来保护关键进程或优先终止非关键进程。例如:

保护关键进程:

echo -17 > /proc/[pid]/oom_score_adj

优先终止非关键进程:

echo 10 > /proc/[pid]/oom_score_adj

六、总结

Linux OOM Killer是一种重要的内存保护机制,在系统内存耗尽时通过终止进程来释放内存,确保系统继续运行。理解OOM Killer的技术原理、工作机制和配置方法,有助于优化系统内存管理,避免内存不足导致的系统崩溃。在实际应用中,可以通过升级64位系统、使用hugemem内核、调整内核参数等方法,优化内存使用,提升系统稳定性。通过合理配置OOM Killer,保护关键进程,优先终止非关键进程,可以有效地管理系统内存,提高系统的可靠性和可用性。

在日常运维和开发过程中,熟悉并掌握OOM Killer的配置和优化技巧,可以帮助我们更好地应对内存紧张的情况,保证系统和应用的稳定运行。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • pytest-bdd 行为驱动自动化测试
  • 防止老年痴呆的小学题
  • DLMS/COSEM中的信息安全:加密算法(下)2
  • 批发行业进销存-登录适配 android 横竖屏幕 源码CyberWinApp-SAAS 本地化及未来之窗行业应用跨平台架构
  • 基于 Redis 的分布式锁 Spring Boot 集成 Redisson 使用分布式锁确保对共享资源的互斥访问
  • 【深度学习】【语音】TTS,StyleTTS 2,论文
  • Android中的沉浸式丝滑转场之共享元素转场动画
  • 机器学习之主成分分析(PCA)
  • Mipi SoundWire Spec 详解4.1
  • sql注入复现(1-14关)
  • linux下的C++程序
  • 【Linux】常见指令
  • 无人机挂载抓捕网
  • 基于Python的数据科学系列(1):Python基础
  • Android HandlerThread泄漏FD问题
  • 收藏网友的 源程序下载网
  • 2017前端实习生面试总结
  • angular组件开发
  • Apache Spark Streaming 使用实例
  • ES10 特性的完整指南
  • IndexedDB
  • JavaScript服务器推送技术之 WebSocket
  • JS变量作用域
  • nodejs实现webservice问题总结
  • NSTimer学习笔记
  • select2 取值 遍历 设置默认值
  • 编写高质量JavaScript代码之并发
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 订阅Forge Viewer所有的事件
  • 坑!为什么View.startAnimation不起作用?
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 小程序 setData 学问多
  • 在Docker Swarm上部署Apache Storm:第1部分
  • # 达梦数据库知识点
  • #Linux(帮助手册)
  • #考研#计算机文化知识1(局域网及网络互联)
  • #每天一道面试题# 什么是MySQL的回表查询
  • (10)STL算法之搜索(二) 二分查找
  • (附源码)php新闻发布平台 毕业设计 141646
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (论文阅读40-45)图像描述1
  • (十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (四) 虚拟摄像头vivi体验
  • (四)库存超卖案例实战——优化redis分布式锁
  • (转)shell中括号的特殊用法 linux if多条件判断
  • (转载)Linux网络编程入门
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • ***监测系统的构建(chkrootkit )
  • **《Linux/Unix系统编程手册》读书笔记24章**
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等
  • .Mobi域名介绍
  • .Net core 6.0 升8.0
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉