只用 -m 无法真正限制内存,必须配对设置 --memory-swap;-m 512m 时默认 --memory-swap=1g,实际可用近1GB,禁用swap需显式设为 --memory-swap=512m。

只用 -m 启动容器,内存限制其实没生效
很多人执行 docker run -m 512m nginx 就以为容器最多只用 512MB 内存,结果 top 里看到进程用了 900MB 还不 OOM——这不是 bug,是 Docker 默认行为。只设 -m 时,--memory-swap 会被自动设为 -m 值的两倍(比如 -m 512m → --memory-swap=1g),意味着容器能用 512MB 物理内存 + 最多 512MB swap,总共近 1GB 才触发 OOM。真正想卡死在 512MB,必须显式配对:docker run -m 512m --memory-swap=512m nginx。
--memory-swap 的值不是“额外 swap”,而是“总上限”
--memory-swap 表示「物理内存 + swap 空间」的总和上限,不是单独给 swap 分配的额度。它的取值直接决定 swap 是否启用:
-
-m 2g --memory-swap=2g:禁用 swap,超 2GB 立即 OOM Kill -
-m 2g --memory-swap=4g:允许最多 2GB swap(4g − 2g = 2g) -
-m 2g --memory-swap=-1:swap 不设限,等同于没做内存保护(生产环境禁用)
注意:--memory-swap 不能小于 -m,否则启动报错:invalid argument: memory-swap must be greater than or equal to memory。
运行中容器也能补加内存限制
已运行的容器不用重启就能加限,用 docker update:
- 补上完整内存+swap 限制:
docker update --memory=1g --memory-swap=1g my-container - 验证是否生效:
docker inspect my-container | grep -i memory,重点看Memory和MemorySwap字段 - 进容器确认底层 cgroup 值:
cat /sys/fs/cgroup/memory/memory.limit_in_bytes(应等于 1073741824)和cat /sys/fs/cgroup/memory/memory.memsw.limit_in_bytes
Docker Compose 里怎么写才真正生效
在 docker-compose.yml 中,只写 mem_limit 是不够的,它只对应 --memory,不控制 --memory-swap。要完整限制,必须用 deploy.resources.limits 块,并显式指定 memory_swap(注意大小写):
services:
api:
image: my-api
deploy:
resources:
limits:
memory: 512M
memory_swap: 512M
如果用的是旧版 Compose(v2 或更早),mem_limit + mem_reservation 无法控制 swap,必须升级到 v3.8+ 并使用 deploy 配置,否则 swap 仍会默认开启。
最容易被忽略的点是:swap 行为由 --memory-swap 单独决定,跟内核版本、Docker Desktop 虚拟机配置都无关;只要没显式设这个参数,就永远存在隐式翻倍风险。


















