首页/系统/Linux 内核与性能调优速查/cgroup v2 memory.high 软限额
内存与 OOM58 条

cgroup v2 memory.high 软限额

软限制:超过后抑制分配、强制回收,进程变慢但不直接被杀;适合“先刹车”再观察的过渡手段。

接口是什么

memory.high 是 cgroup v2 的内存软限额:用量超过它后内核不会立刻杀进程,而是对该组的分配做抑制并施加高强度的回收压力,进程明显变慢但不至于被终止。它适合「先刹车再观察」的过渡阶段,或作为比 memory.max 更温和的隔离手段;是否真的触发过,要看 memory.events 里 high 行的计数,以及 memory.pressure 给出的停顿比例。

基本信息

接口路径/sys/fs/cgroup/<组>/memory.high 与 memory.events
取值字节数(可写 1G 这类后缀)或 max 表示不限制
触发行为抑制分配 + 高强度回收,进程变慢但不被 OOM 终止
systemd 对应MemoryHigh=
相邻接口memory.max(硬限额)、memory.current / memory.peak(用量与峰值)
cgroup 版本仅 cgroup v2 提供;v1 没有该接口

典型使用场景

  • 容器内存缓慢增长时先设软限额,观察是否会被回收压回,避免直接触发 OOM
  • 多租户混部:给次要服务设 memory.high,优先保护关键服务的响应
  • 新服务上线探测真实内存需求:逐步收紧软限额,看触发次数与性能劣化的关系
  • 排查「内存没超 max 但延迟升高」:很可能是 high 触发的回收压力在作祟
  • 与 PSI 联用,量化软限额带来的停顿代价,作为是否需要扩容的依据

查看与设置

查看与设置
cat /sys/fs/cgroup/myapp.slice/memory.current  # 当前用量
cat /sys/fs/cgroup/myapp.slice/memory.high  # 软限额
cat /sys/fs/cgroup/myapp.slice/memory.events  # 其中 high 行是累计触发次数
cat /sys/fs/cgroup/myapp.slice/memory.pressure  # 该组内存侧的停顿压力(PSI)
echo 1G | sudo tee /sys/fs/cgroup/myapp.slice/memory.high  # 运行时设置软限额
cat /sys/fs/cgroup/myapp.slice/memory.high  # 复核写入结果
systemctl set-property myapp.service MemoryHigh=1G  # 通过 systemd 持久化(生成 drop-in)

限额口径对照

接口触发后的行为典型用途
memory.high抑制分配并施加回收压力,变慢但存活过渡期刹车、软隔离
memory.max继续回收,仍不足则触发 OOM 终止硬上限,保护整机
memory.low尽力保护,不强制给关键服务保底但允许在压力下被回收
memory.min强保护,不可被回收关键常驻内存的保护
high 与 max 差距过大时,进程可能长期停在 high 附近反复被回收:表现为延迟升高而不是崩溃,监控里看不到 OOM 事件,只有 memory.events 的 high 计数与 PSI 曲线能揭示问题。
触发软限额会带来额外的回收开销(kswapd 与直接回收),因此 CPU 使用率与延迟可能同时上升。评估调参效果时要同时看内存、CPU 与 PSI 三类指标,避免只盯内存用量得出结论。

易错点

  • 把 memory.high 当硬限额:超限后不会杀进程,只是变慢,与「限死内存」的预期完全不同
  • 忽略回收带来的 CPU 开销:只监控内存指标会漏掉延迟与 CPU 上升的真正原因
  • 把 high 设得过低:服务长期处于被压制状态,性能劣化但没有任何告警事件
  • 不做触发验证:设完不看 memory.events 与 PSI,无法确认限额是否真的起作用
  • 在 cgroup v1 系统上寻找该接口:v1 没有 memory.high,需先确认运行时用的是哪一版 cgroup

数据来源与参考

  • Linux 内核 Documentation/admin-guide/cgroup-v2.rst
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌