Linux cgroup v2 memory.events 中 high 与 oom 如何区分
Linux cgroup v2 中,memory.events 的 high 和 oom 不是同一个级别的告警:high 表示工作负载越过 memory.high 后被节流并进行直接回收,oom 表示已经触到内存限制,新的分配可能失败。前者重点看性能抖动,后者重点看分配失败和进程被杀。
官方文档:https://docs.kernel.org/admin-guide/cgroup-v2.html
快速判断:只有high增长,先查软上限和回收延迟;oom或oom_kill增长,则要按硬上限、分配失败和进程退出路径排查。不要把high计数直接当成 OOM。
先看字段:high、max、oom 和 oom_kill 各自说明什么
memory.events 是按键值记录的事件计数器,常见字段可以按严重程度和处置动作分开理解:
| 字段 | 含义 | 优先关注 |
|---|---|---|
high | 超过 memory.high,任务被节流并执行直接回收 | 延迟、吞吐和软上限是否过低 |
max | 使用量接近或越过 memory.max,内核尝试把它压回边界 | 硬限制、回收是否能释放空间 |
oom | 达到限制且分配即将失败,进入 OOM 状态的次数 | 失败分配和 OOM 处置路径 |
oom_kill | 该 cgroup 中被 OOM killer 杀掉的进程次数 | 退出进程、重启与工作负载影响 |
因此,high 更像“内存预算已经影响性能”的信号,oom 更像“继续分配已经有失败风险”的信号。它们可以先后出现,也可能只出现其中一种;不能只看一个字段就推断完整根因。

看限制:为什么 high 通常先影响性能,oom 才逼近失败
memory.high 是内存控制器的软边界。超过它后,cgroup 内的任务会被限制运行并被引导执行直接回收,目标是给管理程序留下调节内存或终止工作负载的机会。这个阶段可能出现请求变慢、GC 或缓存回收频繁,但不等于已经发生 OOM killer。
memory.max 是硬边界。内核会先尝试回收;如果无法把使用量降回限制以内,分配就可能进入 OOM 状态。oom 增长说明已经走到这个边界附近,oom_kill 是否增长则取决于最终是否真的有进程被 OOM killer 处置。
可以把两者看成两种不同的选型:想提前控制延迟,调优 memory.high;想限制工作负载最大占用,使用 memory.max,同时为 OOM 和恢复预留处理方案。提高 memory.high 不会改变 memory.max,设置 memory.max 也不会消除已经发生的 high 计数。
看归属:先区分层级统计,再判断当前用量
排查时不要只复制一行计数器。memory.events 的字段是层级统计,可能包含后代 cgroup 的事件;如果只想看当前 cgroup 自己产生的事件,应读取 memory.events.local。事件文件记录的是累计次数,不是当前内存用量,实时用量要结合 memory.current。
# 把目标 cgroup 改成实际的服务目录 CG=/sys/fs/cgroup/my-service # 读取层级事件:可能包含后代 cgroup 的贡献 cat "$CG/memory.events" # 只看当前层级事件,适合判断本组是否直接触发 cat "$CG/memory.events.local" # 读取当前用量和两道内存边界,单位通常为字节 printf 'current='; cat "$CG/memory.current" printf 'high='; cat "$CG/memory.high" printf 'max='; cat "$CG/memory.max" # 记录关键进程的 cgroup 归属,避免把别的服务计数算进来 cat /proc/"$PID"/cgroup
上面的命令只展示读取接口。若 memory.events 的 high 很高,而 memory.events.local 较低,优先检查后代服务是否在制造压力;若两者都高,再看当前 cgroup 自己的限制和进程归属。

按组合选动作:三种常见结果不要混为一谈
只有 high 增长:说明工作负载频繁越过 memory.high。先比较 memory.current、memory.high 与请求延迟,检查缓存、批处理或并发峰值是否让软边界过紧;如果业务可以承受更高峰值,再评估提高软边界或优化峰值分配。
oom 增长但 oom_kill 暂时不变:说明分配已经走到硬限制附近,但不代表一定已经杀进程。检查分配重试、调用方是否允许 OOM killer、限制值是否作用在预期层级,并结合服务日志判断请求是否失败。
oom 和 oom_kill 一起增长:按实际进程退出处理。记录被杀进程、父子进程关系、服务管理器的重启原因和 cgroup 层级;如果是多进程服务,还要确认主进程与 worker 是否属于同一个工作负载。不要只把 memory.max 调大而跳过泄漏、缓存和批量峰值的排查。
决策表:什么时候调 high,什么时候处理 max
| 现象 | 首要判断 | 建议动作 |
|---|---|---|
| high 持续增加,oom 为 0 | 软边界造成节流回收 | 查延迟、回收频率和工作集,必要时调整 memory.high |
| max、oom 增加,oom_kill 为 0 | 硬边界附近出现分配失败风险 | 查 memory.max、分配重试和请求失败日志 |
| oom_kill 增加 | 已有进程被 OOM killer 处置 | 保留 PID、归属、退出原因并检查恢复策略 |
| 层级 high 高、本地 high 低 | 压力主要来自后代 cgroup | 逐级读取 memory.events.local,定位实际产生者 |
最后记住三个边界:事件计数器是累计值,不是实时用量;层级文件可能包含后代贡献,不等同于本地事件;high 是节流与回收信号,oom 才表示分配已经逼近失败。按这三点读取,基本就能避免把性能问题误判成 OOM,或把真实 OOM 当成普通内存抖动。
相关问题
high 增长是不是说明内存泄漏?
不一定。它只能说明使用量越过 memory.high 并触发了节流回收,可能来自合法的工作集、缓存或瞬时并发峰值。要判断泄漏,还要观察 memory.current 的长期趋势和分配来源。
oom 增长后一定会看到 oom_kill 吗?
不一定。oom 记录的是达到限制且分配即将失败的事件,最终可能表现为分配失败、重试或 OOM killer 处置;只有真的杀掉进程时,oom_kill 才会随之增加。
Python logging 怎样为异常记录 traceback 但避免重复输出
- 上一篇
- Python logging 怎样为异常记录 traceback 但避免重复输出
- 下一篇
- Linux PSI 怎样读取 memory pressure 的平均值
-
- 文章 · linux | 1小时前 |
- ip route 怎样判断策略路由命中了哪个表
- 175浏览 收藏
-
- 文章 · linux | 1小时前 |
- journalctl 怎样按 PRIORITY 筛选错误级别日志
- 486浏览 收藏
-
- 文章 · linux | 1小时前 | Linux · systemd systemctl show unit状态
- systemd 怎样用 unit 状态属性做脚本判断
- 448浏览 收藏
-
- 文章 · linux | 1天前 |
- Linux systemd 怎样查看服务真实失败原因
- 117浏览 收藏
-
- 文章 · linux | 1天前 |
- Linux ulimit 怎样判断文件句柄上限
- 125浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 669次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 686次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 733次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 701次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 536次使用
-
- 详解golang执行Linuxshell命令完整场景下的使用方法
- 2023-01-07 426浏览
-
- go程序部署到linux上运行的实现方法
- 2023-01-02 387浏览
-
- Linux系统下Go语言开发环境搭建
- 2023-01-07 242浏览
-
- 使用golang获取linux上文件的访问/创建/修改时间
- 2022-12-31 238浏览
-
- 在Linux系统中安装Go语言的详细教程
- 2022-12-29 402浏览

