Linux限制进程内存分两类:ulimit适合临时测试,仅限当前shell子进程且-m不可靠;cgroup v2是生产唯一推荐方式,含systemd-run(一次性任务)和systemd service(持久服务)两种落地形式。

Linux 中限制进程可用的最大内存,核心思路是区分“单个进程临时限制”和“进程组长期可控限制”。前者简单快捷但精度低、易绕过;后者才是生产环境真正可靠的方式。
ulimit 适合快速测试或开发调试
ulimit 是 shell 级资源限制命令,对当前终端及其启动的子进程生效,设置后立即起效,无需 root 权限(软限制),但有明显局限:
-
-m 限制的是 RSS(常驻内存,即物理内存),单位 KB,例如
ulimit -m 524288表示最多用 512MB 物理内存; -
-v 限制的是虚拟内存(AS),含交换空间,更常用,例如
ulimit -v 1073741824表示最多用 1GB 虚拟内存; - 限制只作用于该 shell 启动的进程树,无法约束已运行进程;
- 内核不强制杀进程,malloc 失败返回 NULL,程序需自行处理;
- 现代 glibc 默认忽略
-m,实际效果不可靠,推荐优先用-v。
cgroup v2 是生产环境唯一推荐方式
cgroup v2 是 Linux 当前标准资源控制机制,能精确限制进程组(包括所有子进程)的物理内存总量,且支持自动清理、OOM 控制和 swap 隔离:
- 确认启用:
mount | grep cgroup2应看到挂载点为/sys/fs/cgroup; - 启用 memory 控制器:
echo "+memory" | sudo tee /sys/fs/cgroup/cgroup.subtree_control; - 创建并设限:
sudo mkdir /sys/fs/cgroup/myapp && echo 1G | sudo tee /sys/fs/cgroup/myapp/memory.max; - 严格物理内存限制需禁用 swap:
echo 0 | sudo tee /sys/fs/cgroup/myapp/memory.swap.max; - 将进程加入:
echo $PID | sudo tee /sys/fs/cgroup/myapp/cgroup.procs(仅对新 fork 子进程有效)。
systemd-run 最适合一次性任务或脚本调用
不用手动建目录、不用记路径,一条命令完成启动+限制,自动处理控制器委派与 cleanup:
- 限制内存并运行命令:
systemd-run --scope -p MemoryMax=512M -- bash -c "python3 script.py"; - 同时限 CPU 和内存:
systemd-run --scope -p CPUQuota=30% -p MemoryMax=1G sleep 600; - 退出后 cgroup 自动销毁,无残留,适合 CI/CD 或定时任务。
服务级持久化用 systemd service 文件
若进程以 systemd service 方式长期运行(如 Web 服务、数据库),直接在 unit 文件中声明限制最稳妥:
- 编辑
/etc/systemd/system/myapp.service,在[Service]段添加:MemoryMax=2GMemorySwapMax=0CPUQuota=75%; - 重载配置:
sudo systemctl daemon-reload; - 重启服务:
sudo systemctl restart myapp; - 限制随服务生命周期存在,不受用户登录状态影响。


















