最可靠方式是进容器执行docker exec -it cat /sys/fs/cgroup/memory.max(cgroup v2)或/sys/fs/cgroup/memory/memory.limit_in_bytes(v1),返回字节数即实际限制值,max表示无限制;docker inspect仅显示原始参数,不反映真实生效值。

直接查容器的内存限制值
容器启动时加了 -m 或 --memory,但你不确定具体设了多少?最可靠的方式是进容器内部读 cgroup 文件:
docker exec -it <container_name_or_id> cat /sys/fs/cgroup/memory.max</container_name_or_id>
注意:Docker 20.10+ 默认使用 cgroup v2,返回的是字节数(比如 1073741824 就是 1GB);如果返回 max,说明没设限制,等价于无上限。
旧版 Docker(cgroup v1)路径是 /sys/fs/cgroup/memory/memory.limit_in_bytes,行为一致。
别依赖 docker inspect 的输出去判断——它只显示你传的参数字符串,不反映实际生效值;比如你写 -m 1g,但宿主没开 swap,memory.max 可能还是 max,而 docker inspect 里却写着 "Memory": 1073741824,这会误导你。
用 docker stats 看实时占用和软性上限
docker stats 不显示硬性内存限制,但它能暴露“是否真被限住了”:
- 如果
MEM USAGE / LIMIT显示类似124MiB / 1GiB,说明限制已生效 - 如果显示
124MiB / 15.6GiB(数字接近宿主总内存),基本等于没设限 - 如果容器 OOM 被杀,
docker stats里对应行会短暂闪现后消失,此时要立刻查docker events或dmesg
这个命令不能替代 cgroup 检查,但它是快速筛查“当前有没有被卡住”的第一反应工具。
为什么 docker inspect 的 Memory 字段不准
docker inspect <container></container> 返回的 HostConfig.Memory 是你当初传进去的原始值,不是运行时真实约束。问题出在几个地方:
- WSL2 底层对
--memory-swap的处理会让实际生效的 memory+swap 总和翻倍(比如-m 512m,实际memory.max可能是536870912,但memory.swap.max是另一回事) - 如果你只设了
--cpus没设-m,HostConfig.Memory会是0,但容器依然能吃光宿主内存 - Docker Desktop 界面里调的滑块,改的是 WSL2 全局内存上限(
.wslconfig),不影响单个容器的-m设置,这两层限制是并存的,inspect根本不体现前者
所以靠 inspect 判断“容器被限了多少”,等于看菜谱猜炒锅温度——看着像,但锅里实际多烫,得拿温度计捅进去量。
WSL2 全局内存上限怎么查
Docker Desktop 在 Windows 上跑容器,真正干活的是 WSL2 虚拟机。它有自己的内存池,不归 Docker 容器参数管——这才是很多人发现 “容器明明只设了 1G,VmmemWSL 进程却占了 12G” 的根本原因。
查当前 WSL2 实际内存用量:
wsl -d docker-desktop --shutdown && wsl -d docker-desktop(先重启确保干净)
然后进 WSL2 终端:free -h 或 cat /proc/meminfo | grep MemTotal
它的上限由 %UserProfile%\.wslconfig 决定,内容类似:
#[wsl2] #memory=4GB #processors=2
但这个文件不存在时,WSL2 默认会动态分配,上限可能高达宿主内存的 80%——你没动过它,就等于放开了闸门。
查不到 .wslconfig?那你的 WSL2 内存策略就是“能吃多少吃多少”,和容器里设的 -m 完全是两套逻辑,必须分开治理。


















