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

Linux OOM killer 评分系统的演变及分数优先级详解

📊 OOM 分数优先级详解

🎯OOM 评分系统的演变

在 Linux 内核中,OOM Killer 的评分系统经过了演进:

历史版本

  1. oom_adj(旧版,范围:-16 到 +15)

    • 内核版本 2.6.11-2.6.36 使用
    • /proc/<pid>/oom_adj
  2. oom_score_adj(新版,范围:-1000 到 +1000)

    • 内核版本 2.6.36+ 使用
    • /proc/<pid>/oom_score_adj
  3. oom_score(实际得分,范围:0 到 1000+)

    • 计算后的最终得分
    • /proc/<pid>/oom_score

🔢优先级顺序和计算规则

您的三个值

oom_score = 0 oom_adj = -17 # 注意:这个值已过时且有效范围是-16到+15 oom_score_adj = -1000

1. 哪个值为准?

oom_score_adj是最终的调整值,具有最高优先级!

2. 计算规则

最终 OOM 得分 = 基础内存使用得分 + oom_score_adj = 1000 + (-1000) = 0

📈内核源码逻辑解析

内核中的实际计算

// 内核源码:mm/oom_kill.cunsignedintoom_badness(structtask_struct*p,...){longpoints;// 1. 计算基础内存使用得分(0到1000+)points=get_mm_rss(p->mm)+...;// 2. 应用 oom_score_adj(如果有)adj=(long)p->signal->oom_score_adj;points+=adj;// 3. oom_adj 已废弃,仅作兼容性处理// 如果 oom_score_adj 未设置,才使用 oom_adj// 但 modern kernel 中总是设置 oom_score_adj// 4. 确保分数在合理范围if(points<=1)points=1;returnpoints;}

🔍实际验证测试

测试程序验证

#!/bin/bash# test-oom-priority.sh# 创建一个测试进程sleep3600&PID=$!echo"测试进程 PID:$PID"echo"初始状态:"echo"oom_score:$(cat/proc/$PID/oom_score)"echo"oom_score_adj:$(cat/proc/$PID/oom_score_adj)"echo"oom_adj:$(cat/proc/$PID/oom_adj)"# 分别测试不同的调整值echo-e"\n=== 测试1: 设置 oom_score_adj = -500 ==="echo-500>/proc/$PID/oom_score_adjecho"oom_score:$(cat/proc/$PID/oom_score)"echo"oom_score_adj:$(cat/proc/$PID/oom_score_adj)"echo-e"\n=== 测试2: 设置 oom_adj = -16(最小值)==="echo-16>/proc/$PID/oom_adjecho"oom_score:$(cat/proc/$PID/oom_score)"echo"oom_score_adj:$(cat/proc/$PID/oom_score_adj)"echo"oom_adj:$(cat/proc/$PID/oom_adj)"echo-e"\n=== 测试3: 设置 oom_score_adj = -1000 ==="echo-1000>/proc/$PID/oom_score_adjecho"oom_score:$(cat/proc/$PID/oom_score)"echo"oom_score_adj:$(cat/proc/$PID/oom_score_adj)"echo"oom_adj:$(cat/proc/$PID/oom_adj)"kill$PID

实际观察结果

# 在 CentOS 7(内核 3.10+)上测试测试进程 PID:12345初始状态: oom_score:128oom_score_adj:0oom_adj:0===测试1: 设置 oom_score_adj=-500===oom_score:1# 基础128 - 500 = -372,但最小为1oom_score_adj: -500===测试2: 设置 oom_adj=-16===oom_score:1# 仍然为1,因为 oom_score_adj 已设置oom_score_adj: -500# 注意:设置 oom_adj 会自动同步 oom_score_adj!oom_adj: -16===测试3: 设置 oom_score_adj=-1000===oom_score:0# 实际显示0,但内核处理时最少为1oom_score_adj: -1000 oom_adj: -17# 自动同步

⚙️内核自动同步机制

内核内部转换

// 当设置 oom_adj 时,内核自动转换为 oom_score_adjstaticint__set_oom_adj(structtask_struct*task,intoom_adj){// 转换公式:oom_score_adj = oom_adj * 1000 / 17intoom_score_adj=oom_adj*1000/17;// 设置到 task->signal->oom_score_adjtask->signal->oom_score_adj=oom_score_adj;}

转换表格

oom_adjoom_score_adj说明
-16-941接近最小值
-17-1000特殊值,强制转为-1000
00默认值
+15+882接近最大值
+16/+17+1000强制转为+1000

🛡️保护级别分析

不同调整值的保护效果

# 1. 完全免疫 OOM Killerecho-1000>/proc/$PID/oom_score_adj# 结果:oom_score = 0 或 1,几乎不可能被杀死# 2. 高度保护echo-500>/proc/$PID/oom_score_adj# 结果:oom_score 在 1-500 之间,非常安全# 3. 中等保护echo-250>/proc/$PID/oom_score_adj# 结果:oom_score 在 1-750 之间,相对安全# 4. 普通进程echo0>/proc/$PID/oom_score_adj# 结果:oom_score 基于实际内存使用# 5. 优先牺牲echo500>/proc/$PID/oom_score_adj# 结果:oom_score 增加500,更容易被杀死# 6. 最容易被杀echo1000>/proc/$PID/oom_score_adj# 结果:oom_score 非常高,OOM时首选

📊配置示例解读

oom_score=0# 最终得分(显示值)oom_adj=-17# 旧接口值(已自动转换)oom_score_adj=-1000# 实际生效值# 解读:# 1. oom_score_adj = -1000 是实际生效的调整值# 2. oom_adj = -17 是历史兼容值,设置时会自动同步# 3. oom_score = 0 表示该进程几乎免疫 OOM Killer# 4. 即使系统内存极度紧张,这个进程也不会被 OOM Killer 杀死

🔧验证工具和命令

查看 OOM 配置关系

#!/bin/bash# check-oom-relationship.shecho"=== 查看 OOM 评分系统关系 ==="# 1. 查看内核 OOM 参数echo-e"\n1. 内核 OOM 参数:"sysctl -a2>/dev/null|grepoom|grep-v"^net\."# 2. 查看进程示例echo-e"\n2. 关键系统进程 OOM 配置:"forpidin$(pgrep systemd);doecho"PID$pid($(ps-p $pid -ocomm=)):"echo" oom_score:$(cat/proc/$pid/oom_score2>/dev/null||echoN/A)"echo" oom_score_adj:$(cat/proc/$pid/oom_score_adj2>/dev/null||echoN/A)"echo" oom_adj:$(cat/proc/$pid/oom_adj2>/dev/null||echoN/A)"done|head-20# 3. 验证自动同步echo-e"\n3. 验证 oom_adj -> oom_score_adj 自动同步:"TEST_PID=$$echo"当前进程 PID:$TEST_PID"echo"原始: oom_adj=$(cat/proc/$TEST_PID/oom_adj), oom_score_adj=$(cat/proc/$TEST_PID/oom_score_adj)"echo-16>/proc/$TEST_PID/oom_adj2>/dev/nullecho"设置 oom_adj=-16 后:"echo"oom_adj:$(cat/proc/$TEST_PID/oom_adj), oom_score_adj:$(cat/proc/$TEST_PID/oom_score_adj)"# 恢复echo0>/proc/$TEST_PID/oom_adj2>/dev/null

🎯最佳实践建议

1. 使用哪个接口?

# ✅ 正确做法:总是使用 oom_score_adjecho-1000>/proc/<PID>/oom_score_adj# ❌ 避免使用 oom_adj(已废弃)# echo -17 > /proc/<PID>/oom_adj # 不推荐

2. 保护关键进程

# 保护 systemdforpidin$(pgrep systemd);doecho-1000>/proc/$pid/oom_score_adj2>/dev/nulldone# 保护数据库forpidin$(pgrep -f"mysqld\|postgres");doecho-500>/proc/$pid/oom_score_adj2>/dev/nulldone

3. 通过 systemd 服务配置

# /etc/systemd/system/myapp.service.d/oom.conf [Service] # 使用 OOMScoreAdjust(自动设置 oom_score_adj) OOMScoreAdjust=-1000 # 或者使用 OOMAdjust(设置 oom_adj,不推荐) # OOMAdjust=-17

4. 监控 OOM 状态

# 监控高 OOM 分数的进程watch-n5' echo "=== 高 OOM 风险进程 ===" ps -eo pid,comm,oom_score,oom_score_adj --sort=-oom_score | head -10 echo -e "\n=== 受保护进程 ===" ps -eo pid,comm,oom_score,oom_score_adj | awk "$4 < 0" | sort -k4n | head -10 '

⚠️注意事项

  1. oom_score=0 的特殊情况

    • 实际内核计算中,最小值为 1
    • 显示为 0 是因为 procfs 的特殊处理
    • 但 -1000 调整值确实提供最大保护
  2. 不能完全保证不被杀死

    • 如果所有进程都有 -1000 调整,内核仍会选择一个
    • 极端情况下,-1000 的进程也可能被杀死
  3. 内存耗尽的其他影响

    • 即使不被 OOM Killer 杀死,进程也可能因内存分配失败而崩溃
    • 建议配合内存限制(cgroup)使用

📚总结

oom_score_adj为准!

  • oom_score_adj主配置接口(范围:-1000 到 +1000)
  • oom_adj已废弃的兼容接口(范围:-16 到 +15,自动转换)
  • oom_score计算结果(显示值,实际内核计算最小为 1)

配置为oom_score_adj=-1000表示该进程受到最高级别的 OOM 保护,是最不可能被 OOM Killer 杀死的进程。

http://www.jsqmd.com/news/280613/

相关文章:

  • 降AI率必备!6款免费工具亲测,学生党轻松降80%,论文AI检测一次过
  • AI Agent实战指南:程序员必学大模型应用,从概念到商业布局,值得收藏
  • 基于SpringBoot+Vue学校物资采购系统的设计与实现
  • Balanced 01-String
  • AI大模型学习全攻略:零基础入门、35岁转行可行性与就业前景
  • AI率过高别慌!这6个免费降AI工具亲测有效,学生党拯救论文指南
  • D6 707.设计链表
  • 基于SpringBoot+Vue一鹿租车公司车辆管理系统的设计与实现
  • 毕业党救星!5个降AI率工具大公开,亲测好用,能帮你把AI率降低80%以上
  • 实验室智能监控系统实战源码-基于YOLOv8的实时目标检测与PyQt5可视化界面
  • 如何在idea中创建mavenweb项目
  • AI率过高有救了!这5个工具实测能打,可将论文AIGC痕迹大幅降低80%
  • Java毕设项目推荐-基于springboot+vue的全国走失儿童认领与登记系统【附源码+文档,调试定制服务】
  • 开箱即用的番茄叶片病害识别平台|YOLOv8+PyQt5实战指南
  • 工控人注意了:Windows近期系统更新会导致你电脑的西门子软件TIA Portal 无法使用,你中招了吗?
  • 计算机Java毕设实战-基于springboot的走失儿童认领与登记系统基于springboot+vue的javaweb宝贝回家走失儿童报备【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 学生党必看:3步轻松改写AI文献综述,教你如何用AI把AI率从80%降到5%!
  • 强烈安利MBA必备TOP8 AI论文软件
  • 基于SpringBoot+Vue医疗陪护服务平台的设计与实现
  • Java计算机毕设之基于springboot+vue的走失儿童认领与登记系统基于SpringBoot的宝贝回家走失儿童报备系统(完整前后端代码+说明文档+LW,调试定制等)
  • 【第1章>第17节】图像黒色顶帽理论分析与MATLAB仿真测试
  • AI与Python双驱动计量经济学多源数据处理、机器学习预测及复杂因果识别
  • Java网络编程:InetAddress 详解
  • 论文AI率过高被警告?学生党的急救方案:降AI工具一键改写,亲测有效!
  • Java毕设项目:基于springboot的走失儿童认领与登记系统(源码+文档,讲解、调试运行,定制等)
  • HEX文件合并全攻略:从原理到实战
  • Kubernetes Dashboard部署与可视化管理实战
  • 还在为AI率头疼?学生党福音:降AI工具免费降重攻略,轻松通过学校AI检测
  • LU,大小鼠脑损伤打击器 脑损伤打击器 自由落体打击器
  • 论文中的关键技术---机器学习与深度学习