Docker容器运行时无法修改CPU硬限制(--cpus),内存限制(--memory)仅在特定条件下可通过docker update动态调整;docker-compose up忽略deploy.resources,须用顶层cpus/mem_limit参数;Docker Desktop内存占用需调WSL2/Hyper-V资源;Java等运行时须启用容器感知参数否则-m无效。

运行中的 Docker 容器无法直接修改 CPU 或内存硬限制(--cpus、--memory),这是内核 cgroups 的硬性约束,不是 Docker Desktop 特有,而是所有 Linux 容器 runtime 的共性。 你看到的 docker update --memory=2g my-container 确实能生效,但仅限内存——且仅当容器使用的是 runc runtime、未启用 systemd cgroup v2 混合模式、且宿主机内核支持动态更新时才可靠;CPU 配额(--cpus)在运行中根本不可调。
docker update 能改什么、不能改什么
它只作用于 memory 和 swap 相关 cgroup 参数,对 CPU 权重(--cpu-shares)可临时调整,但对 --cpus 或 --cpuset-cpus 无效。实际效果取决于底层 cgroup 版本和 runtime 行为:
-
docker update --memory=1g my-container:多数情况下成功,但若容器已接近 OOM 边界,可能触发立即 kill -
docker update --memory-swap=2g my-container:需原启动时已设--memory,否则报错“invalid argument” -
docker update --cpu-shares=2048 my-container:仅在 CPU 竞争时起作用,不改变最大可用时间片 -
docker update --cpus=2 my-container:直接报错OCI runtime error: cannot update cpu quota
为什么 docker-compose up 不认 deploy.resources 的限制
单机模式下 docker-compose up 完全忽略 deploy.resources —— 这个字段只被 Docker Swarm 的 docker stack deploy 解析。你写进 docker-compose.yml 的这段配置:
deploy:
resources:
limits:
cpus: '1.5'
memory: 512M
在本地执行 docker-compose up 时形同注释。真正生效的写法是退回到顶层参数:
services:
app:
image: nginx
cpus: 1.5
mem_limit: 512m
注意:cpus 和 mem_limit 是 Compose v2+ 的顶层字段,不是 deploy 下的子项;它们会被翻译成 docker run --cpus --memory 参数,但前提是用 docker compose up(v2 CLI),而非旧版 docker-compose(v1)。
Docker Desktop 本身吃内存,不是容器的问题
你在 docker stats 里看到容器 RSS 总和才 1.2GB,但系统却卡死、Activity Monitor 显示 Docker Desktop 占 3.8GB——这说明瓶颈在 WSL2/Hyper-V 虚拟机层,而非容器配额。此时调 -m 毫无意义,必须先管住 VM:
- macOS:设置 → Resources → Advanced → 把 Memory 调到 6GB(别超物理内存 40%)
- Windows:必须创建
%USERPROFILE%\.wslconfig,内容至少含memory=6GB和processors=4,然后wsl --shutdown再重启 Docker Desktop - 验证是否生效:启动一个 Ubuntu WSL 发行版,运行
free -h,total 行应接近你设的值
没做这步就去调容器 --memory,等于在漏水的桶里舀水——源头没堵住。
Java 容器不加 JVM 容器感知参数,-m 就是摆设
哪怕你给容器设了 --memory=1g,JVM 默认仍按宿主机总内存(比如 16GB)算堆大小,-Xmx 可能自动设到 4GB,结果一启动就被 OOM Killer 杀掉。必须显式传参:
docker run -e JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0" -m 1g openjdk:17-jre
关键点:
-
-XX:+UseContainerSupport(JDK 10+ 默认开启,但旧镜像可能关着) -
-XX:MaxRAMPercentage比-Xmx更安全,它按容器cgroup.memory.limit_in_bytes动态计算 - 别信镜像文档写的“已优化”,检查
java -XX:+PrintFlagsFinal -version | grep MaxRAM确认值是否合理
最常被忽略的,是以为设了 -m 就万事大吉;其实 JVM、Node.js、.NET Runtime 都要各自适配容器内存边界,否则 -m 形同虚设。


















