cgroup v2 中通过 memory.max 设硬上限、memory.oom 启用组内 oom 控制、memory.oom.group 实现线程组批量终止,并结合 memory.pressure 和 memory.events 主动干预,避免依赖全局 oom killer。

直接用 cgroup 的 memory.oom 和 memory.oom.group 可以精细控制内存耗尽时杀谁、怎么杀,而不是依赖全局 OOM Killer 无差别收割。
明确 cgroup 版本差异,避免配置失效
cgroups v1 和 v2 的接口和行为完全不同,混用会导致限制不生效或行为异常:
- v1 使用
memory.oom_control(写入0禁用 OOM killer,1启用),但已逐步淘汰; - v2 统一为
memory.oom(0禁用,1启用),且默认开启; - v2 中必须先设
memory.max才会触发 OOM 判定,仅设memory.high不会杀进程; - RHEL 8+/CentOS 8+、Ubuntu 20.04+ 默认启用 cgroup v2,手动挂载
memory子系统可能失败,应直接使用/sys/fs/cgroup下的统一层级。
设置硬上限并启用 OOM 控制
这是自定义保护策略的基础动作:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 创建 cgroup 目录:
sudo mkdir /sys/fs/cgroup/myapp; - 设内存硬上限(如 512MB):
echo 536870912 | sudo tee /sys/fs/cgroup/myapp/memory.max; - 启用本组 OOM killer:
echo 1 | sudo tee /sys/fs/cgroup/myapp/memory.oom; - 验证是否生效:检查
cat /sys/fs/cgroup/myapp/memory.oom输出为1,且memory.max值正确。
按业务逻辑决定“杀一个”还是“清全场”
默认 OOM killer 每次只终止一个进程,但很多服务(如 Java 应用、Node.js 多线程服务)多个线程共享堆,单杀主线程后子线程仍驻留内存,导致限流失效:
- 启用批量终止:
echo 1 | sudo tee /sys/fs/cgroup/myapp/memory.oom.group; - 效果:OOM 触发时,内核将杀死该 cgroup 内所有属于同一线程组(即同一
pid的所有tid)的进程; - 注意:若应用是主从多进程模型(如 Nginx master-worker),启用后可能中断服务逻辑,需实测验证;
- 不启用时,可通过
oom_score_adj调整进程被选中的优先级(范围 -1000~1000),值越高越容易被杀。
配合监控与压力信号做主动干预
等 OOM 发生再响应太晚,应结合压力指标提前干预:
- 监听轻量级压力信号:
cat /sys/fs/cgroup/myapp/memory.pressure,输出类似some 0.00 0.00 0.00,其中第三个数字是 critical 级别持续压力(单位秒); - 采集关键事件:
cat /sys/fs/cgroup/myapp/memory.events查看oom和oom_kill计数,持续增长说明容量不足; - 在接近
memory.high(如设为 450M)时,内核会主动回收该 cgroup 内存,可配合此值做弹性扩缩或告警; - 禁止 OOM 杀进程而改用阻塞分配(慎用):
echo 0 | sudo tee /sys/fs/cgroup/myapp/memory.oom,此时malloc返回NULL,应用需自行处理失败路径。










