无法直接限制单个已有进程的物理内存峰值,cgroup按进程组管理资源;推荐启动时用systemd-run绑定memorymax和memoryswapmax=0实现硬限,或手动迁移至cgroup(不保证子进程继承且不回收已有内存)。

直接限制单个已有进程的物理内存峰值,在 Linux 中无法做到“事后精准控制”。cgroup 的设计逻辑是按进程组(task group) 管理资源,不是给单个 PID 打补丁。但你可以通过以下两种方式有效达成目标:一种是启动时就约束(推荐),一种是尝试迁移(有局限性,不保证子进程继承)。
✅ 启动时用 systemd-run 绑定硬性内存上限(最可靠)
这是生产环境和脚本化场景的首选,能真正限制其物理内存使用峰值(RSS),且自动处理子进程继承、控制器启用、清理等细节。
systemd-run --scope -p MemoryMax=1G -p MemorySwapMax=0 python3 train.py
-
MemoryMax=1G:限制该 scope 内所有进程的总物理内存 + swap 使用量上限为 1GB -
MemorySwapMax=0:关键一步——禁用交换,确保限制的是纯物理内存(RSS),否则进程可能把数据换出到 swap,绕过物理内存限制 - 进程及其所有 fork 出的子进程、线程都受控
- scope 退出后自动清理,无残留
⚠️ 注意:单位写
1G(大写 G)或1073741824,不能写1g或1GB;0或max表示不限制。
⚠️ 尝试将已有进程迁入 cgroup(仅限简单场景,慎用)
适用于没有子进程、不频繁 fork 的短命进程(如一个孤立的 sleep 1000)。对 Java、Python、Node.js 等会动态派生子进程/线程的应用,极易失效。
步骤:
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
-
确认系统启用 cgroup v2 及 memory 控制器:
mount | grep cgroup2 cat /sys/fs/cgroup/cgroup.controllers | grep memory # 若未启用,执行: echo "+memory" | sudo tee /sys/fs/cgroup/cgroup.subtree_control
-
创建限制组并设上限(例如 512MB 物理内存):
sudo mkdir /sys/fs/cgroup/limit-512m echo 536870912 | sudo tee /sys/fs/cgroup/limit-512m/memory.max echo 0 | sudo tee /sys/fs/cgroup/limit-512m/memory.swap.max
-
把目标进程 PID 写入:
echo 12345 | sudo tee /sys/fs/cgroup/limit-512m/cgroup.procs
- ✅ 此时该进程后续的内存分配(malloc、mmap 等)若超限,会立即失败(返回 NULL)或触发 OOM killer 杀掉它自己(取决于 workload 和内核策略)
- ❌ 但它已存在的内存占用(如已 malloc 的 400MB)不会被回收,峰值不会下降,只是阻止进一步增长
- ❌ 它 fork 的新进程默认不属于该 cgroup,除非父进程显式设置
clone(2)的CLONE_INTO_CGROUP(极少见)
❌ ulimit -m 不起作用(已废弃,勿用)
ulimit -m 限制的是 RSS(驻留集大小),但自 Linux 2.6.35+ 起已被内核忽略,实际无效。现代发行版中运行 ulimit -m 100000 后测试,进程仍可突破该值。不要依赖它。
? 验证是否生效
- 查看当前 cgroup 内存使用:
cat /sys/fs/cgroup/limit-512m/memory.current cat /sys/fs/cgroup/limit-512m/memory.max
- 查看进程归属:
cat /proc/12345/cgroup | grep limit-512m
- 观察 OOM 日志(若超限被杀):
dmesg -T | grep -i "killed process"
不复杂但容易忽略










