Docker Desktop图形界面设置的是引擎宿主机内存上限,非容器软限制;单个容器软限制必须用docker run --memory-reservation显式配置,且须搭配--memory硬限制,值须更小,仅创建时生效,不可docker update动态修改。

docker run 时用 --memory-reservation 才管用
Docker Desktop 的图形界面(Preferences → Resources → Advanced)里调的内存,是给整个 Docker Engine 分配的宿主机内存上限,不是给单个容器设软限制。想给某个容器加内存软限制,必须在 docker run 命令里显式传参,靠 GUI 是设不了的。
常见错误是以为调高了 Docker Desktop 的“Memory”滑块(比如调到 6GB),容器就自动有了软限制——其实那只影响 dockerd 进程能用多少内存,和容器内部的 cgroup 内存策略完全无关。
-
--memory-reservation必须搭配--memory使用,否则会被忽略 - 软限制值必须严格小于硬限制值,例如
--memory-reservation 512m配--memory 1g合法,配--memory 512m会报错 - 软限制只在系统内存压力下触发回收,平时容器可以继续用到硬限制值
docker update 不支持动态修改 --memory-reservation
你不能对已运行的容器用 docker update 补上软限制。这个参数只在容器创建时生效,后续调用 docker update --memory-reservation 512m my-container 会直接报错:unknown flag: --memory-reservation。
如果发现线上容器缺软限制,只能停掉重建。别指望热更新——cgroups v2 的 memory.soft_limit_in_bytes 在容器启动后就固定了,Docker CLI 没暴露运行时写入接口。
- 硬限制(
--memory)可以用docker update修改 - 但软限制、swap、kernel memory 等多数 memory 子系统参数都不支持 update
- Compose 场景下,得改
deploy.resources.limits.memory并docker-compose up -d --force-recreate
验证软限制是否生效:看 cgroup 文件和 stats 输出
跑起来之后,不能光信命令没报错,得进容器或宿主机确认底层 cgroup 是否写入成功。最直接的方式是查容器对应的 cgroup 目录:
docker exec -it my-container cat /sys/fs/cgroup/memory.max docker exec -it my-container cat /sys/fs/cgroup/memory.soft_limit_in_bytes
前者应等于你设的 --memory 值(如 1073741824),后者应等于 --memory-reservation 值(如 536870912)。如果 memory.soft_limit_in_bytes 显示 9223372036854771712,说明没生效(这是 cgroup 默认的极大值)。
-
docker stats my-container只显示当前使用量和硬限制,不体现软限制 - 软限制行为只能通过压测触发:用
stress-ng --vm 1 --vm-bytes 800M模拟内存压力,观察是否被回收到软限以下 - 宿主机上可查
dmesg | grep -i "memory\|oom"看内核是否按软限做了优先级调度
Mac 上 Docker Desktop 的 cgroup 路径藏得更深
Mac 用户容易在这一步卡住:你在容器里执行 cat /sys/fs/cgroup/memory.soft_limit_in_bytes 总是返回默认值,不是因为你参数错了,而是 Docker Desktop for Mac 底层用的是 LinuxKit VM,真正的 cgroup 文件在虚拟机里,容器内看到的是挂载的只读视图。
正确验证方式是进 LinuxKit VM:
screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
# 登录后执行
cat /sys/fs/cgroup/system.slice/docker-$(docker inspect -f '{{.ID}}' my-container).scope/memory.soft_limit_in_bytes或者更简单:用 docker run 启动一个带 --memory-reservation 的容器后,立刻在宿主机(Mac 终端)执行:
docker inspect my-container | jq '.[].HostConfig.MemoryReservation'
只要输出是数字(非 0 或空),就代表参数已传入,软限制逻辑由内核在 VM 内执行,你无需、也无法在 macOS 主机侧直接观测 cgroup 文件。
真正容易被忽略的点是:软限制不是“保证容器有这么多内存”,而是“告诉内核:当别人也抢内存时,请先动它”。它不防 OOM,只调回收顺序。如果你的应用本身就有内存泄漏,软限制救不了它——该杀还是杀。


















