Docker通过--memory和--memory-swap参数直接映射cgroups v1的memory.limit_in_bytes与memory.memsw.limit_in_bytes,前者限制物理内存上限,后者限制内存+swap总和(必须≥前者),共同防止宿主机OOM。
直接通过 Docker 的 --memory 和 --memory-swap 参数就能生效,它们底层就是写入 cgroups v1 的 memory controller 文件。关键不是手动改 cgroup,而是理解这两个参数如何映射到物理内存与 swap 的硬性边界。
该参数对应 cgroups v1 中的 memory.limit_in_bytes,限制容器能使用的最大物理内存字节数。超出即触发 OOM Killer 杀进程。
--memory=256m → /sys/fs/cgroup/memory/docker/<id>/memory.limit_in_bytes 显示 268435456
0 表示不限制(不推荐),设太小会导致 Java 等应用启动失败--memory-swap
--memory-swap 不是单独的 swap 上限,而是“物理内存 + swap”的总和上限,对应 memory.memsw.limit_in_bytes。它的值必须 ≥ --memory,否则报错。
--memory=256m --memory-swap=768m → 最多用 256MB 物理内存 + 512MB swap--memory=256m --memory-swap=256m → swap 被禁用(memory.memsw.limit_in_bytes == memory.limit_in_bytes)--memory=256m --memory-swap=-1 → 物理内存仍限 256MB,但 swap 不设上限(需宿主机有 swap 分区)不能只看 free -h 或 swapon -s,容器内通常看不到 swap 设备。要确认限制已写入 cgroups:
cat /sys/fs/cgroup/memory/memory.limit_in_bytes 和 cat /sys/fs/cgroup/memory/memory.memsw.limit_in_bytes
docker inspect <容器名> | jq '.[0].HostConfig.Memory, .[0].HostConfig.MemorySwap'
docker stats <容器名> --no-stream,其中 “MEM USAGE / LIMIT” 的 LIMIT 是 memory+swap 总和如果配置了但没效果,大概率是内核或 Docker 没启用 swap accounting:
zgrep CONFIG_MEMCG_SWAP /proc/config.gz 或 grep MEMCG_SWAP /boot/config-$(uname -r),应为 y
swapon --show 非空--no-swappiness 类参数,且 /etc/docker/daemon.json 中未覆盖相关 ulimit 或 cgroup 设置