cgroup v2 废弃了 oom_adj 和 oom_score_adj 的 per-process 调控,OOM 优先级由 memory.oom.group 和 memory.max 等 cgroup 级配置决定;写入 /proc/PID/oom_score_adj 被内核忽略,属架构移除而非权限问题。

为什么 oom_adj 和 oom_score_adj 在 cgroup v2 下不生效
cgroup v2 完全废弃了 v1 的 oom_adj(对应 /proc/PID/oom_adj)和 oom_score_adj(/proc/PID/oom_score_adj)的 per-process 调控逻辑。v2 把 OOM 优先级控制收归到 memory controller 层级,只认 memory.oom.group 和整体 memory.high/memory.max 等边界设置。写入任何值到 /proc/PID/oom_score_adj 不会报错,但内核直接忽略——这不是权限或路径问题,是架构层面移除。
memory.oom.group 的真实作用和常见误用
memory.oom.group 不是“开启 OOM 分组保护”,而是决定:当该 cgroup 触发 OOM 时,内核是否只 kill 本 cgroup 内的进程(1),还是允许跨 cgroup 杀(0,默认)。它不改变 OOM 选择哪个进程被杀,也不影响 oom_score_adj 的历史值。
- 设为
1:OOM 发生时,只在当前 cgroup 子树中选 victim,哪怕其他 cgroup 更“该死” - 设为
0:内核按全局oom_score排序,可能杀掉兄弟 cgroup 里的进程 - 必须配合
memory.max使用才有意义;若没设内存上限,根本不会触发 cgroup-level OOM - 只对 direct reclaim(即真正内存耗尽)生效,不干预 memcg reclaim 或 page cache 回收
想调控某个进程的 OOM 倾向性?只能靠 cgroup v2 的层级与配额
v2 下没有 per-process OOM 权重,唯一可行路径是把目标进程放入独立 cgroup,并通过资源限制间接影响其被 kill 的概率:
- 给关键进程建专属 cgroup:
/sys/fs/cgroup/my-critical-app - 设宽松上限:
echo "512M" > memory.max(避免过早触发 OOM) - 设
echo 1 > memory.oom.group(防止它被“连坐”) - 非关键进程放入另一个 cgroup 并设更激进的
memory.low或更低memory.max,提高其被优先回收的概率 - 注意:
memory.oom.group对 root cgroup 无效,且不能动态继承——子 cgroup 必须显式设置
验证是否真生效:别只看文件写入成功,要看 OOM 日志和实际行为
写入 memory.oom.group 成功不代表 OOM 行为如你所愿。真正判断依据只有两个:
- dmesg 中 OOM killer 日志是否出现
Task in /my-critical-app killed(而非父路径或其它路径) - 当多个 cgroup 同时超限,观察是否仅
memory.oom.group=1的那个 cgroup 内进程被 kill - 用
cat /sys/fs/cgroup/my-critical-app/cgroup.events查看oom字段是否递增 - 如果
memory.max是max(无限制),memory.oom.group永远不会触发——这点最容易被忽略










