关键是在物理内存不足时通过cgroup v2的memory.high主动触发轻量级回收,配合memory.low保底热页、memory.pressure实时感知,实现比OOM Killer更柔和、比软限更可控的内存管理。

在物理内存不足时让容器内存被强制回收,关键不是“等系统OOM Killer动手”,而是提前用 cgroup v2 的 memory 控制器主动施加压力响应机制。核心思路是:设好 memory.low 保底弹性空间 + memory.high 主动回收阈值,再配合 memory.pressure 实时感知,触发内核级回收动作——这比硬限(memory.max)更柔和,也比软限(--memory-reservation)更可控。
设置 memory.high:内存压力下的第一道回收开关
memory.high 是 cgroup v2 中最实用的主动回收参数。它不阻止容器使用更多内存,但一旦实际用量超过该值,内核就会立即启动轻量级内存回收(reclaim),尝试把不活跃页(如匿名页缓存、文件页)释放掉,而不会直接杀进程。
- 例如,为容器组
ai-infer设置 1.2GB 高水位:echo 1288490188 > /sys/fs/cgroup/ai-infer/memory.high - 这个值应略高于容器典型 RSS(比如实测稳定在 800MB),留出缓冲余量;但必须低于
memory.max(硬上限),否则无效。 - 当
memory.current持续超过memory.high,memory.pressure中的some值会明显升高(如 >0.03),就是回收已启动的信号。
搭配 memory.low:保护关键内存不被误收
仅设 memory.high 可能导致回收过于激进,把容器正在使用的热页也扫掉。此时 memory.low 就起“弹性保底”作用——它告诉内核:“这部分内存请尽量别动,除非系统整体濒临 OOM”。
- 对推理容器,可设为典型工作集大小(如 600MB):
echo 644245094 > /sys/fs/cgroup/ai-infer/memory.low - 注意:
memory.low不是硬锁,它只在内存压力下生效;也不会抢占其他 cgroup,只是提升本组页的“回收难度”。 - 避免与
memory.min混用:memory.min是强锁定,会直接导致其他组饥饿,AI 负载场景中极少需要。
验证与监控:确认回收是否真实触发
光设参数不够,得看到回收动作发生才算落地。重点盯三个文件:
-
cat /sys/fs/cgroup/ai-infer/memory.pressure:持续观察some值。若稳定在 0.01–0.05,说明内核正周期性回收;突增至 >0.1 则表明压力加剧。 -
cat /sys/fs/cgroup/ai-infer/memory.stat:查找pgpgin/pgpgout(页入/出量)、pgmajfault(主缺页次数)。回收活跃时,pgpgout会明显上升。 -
cat /sys/fs/cgroup/ai-infer/memory.current对比memory.high:若current在高压下回落并稳定在 high 附近,说明回收有效。
容器运行时适配:Docker/K8s 中如何落地
原生命令行操作适合调试,生产环境建议走标准接口:
- Docker 启动时启用 cgroup v2 并透传参数:
docker run --cgroup-parent=ai-infer --memory=2g --memory-reservation=800m ...
再手动向/sys/fs/cgroup/ai-infer/写入memory.high和memory.low。 - Kubernetes 中,通过
pod.spec.containers[].resources.limits.memory设硬限后,在节点上用 systemd 或自定义 init 容器写 cgroup v2 参数到对应kubepods.slice子路径下。 - 务必关闭 swap(
swapoff -a)或设memory.swap.max=0:避免回收时把匿名页换出,掩盖真实内存压力。


















