Linux-Docker容器内存优化
一、整体优化思路(非常重要)
系统内存优化不是单点,而是三层结构:
[ 应用层 JVM ] ↓ [ 容器层 Docker ] ↓ [ 系统层 Linux ]👉 优化必须三层一起做,否则无效
🐳 二、Docker 容器内存优化
1️⃣ 查看内存占用 Top N
✔ Top10(推荐)
docker stats --no-stream --format "{{.Name}} {{.MemUsage}}" \ | sort -k2 -h -r | head -n 10✔ 带百分比 Top10
docker stats --no-stream --format "table {{.Name}}\t{{.MemUsage}}\t{{.MemPerc}}" \ | sort -k3 -h -r | head -n 112️⃣ 容器内存限制(关键)
--memory=1g --memory-swap=1g👉 作用:
- 限制容器最大使用内存
- 防止宿主机被打爆
⚠️ 常见问题
- 没限制 → JVM 无限吃内存
- 限制太大 → 无意义
- 限制太小 → OOM
🎯 推荐分级
| 服务类型 | 内存 |
|---|---|
| 工具服务 | 512M |
| 普通服务 | 768M ~ 1G |
| 核心服务 | 1G ~ 2G |
| 中间件 | 独立调优 |
☕ 三、JVM 内存优化(核心)
1️⃣ Java 8(不推荐但常见)
-Xms256m -Xmx768m -XX:MaxMetaspaceSize=192m -XX:MaxDirectMemorySize=256m 不换行JDK8 ENTRYPOINT ["java","-Xms256m","-Xmx768m","-XX:+UseContainerSupport","-XX:MaxRAMPercentage=60","-XX:MaxMetaspaceSize=192m","-XX:MaxDirectMemorySize=256m","-Djava.security.egd=file:/dev/./urandom","-jar","app.jar"]2️⃣ Java 17(推荐)
-Xms256m -Xmx768m -XX:+UseContainerSupport -XX:MaxMetaspaceSize=192m -XX:MaxDirectMemorySize=256m --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED 不换行JDK17 ENTRYPOINT ["java","-Xms256m","-Xmx768m","-XX:+UseContainerSupport","-XX:MaxRAMPercentage=60","-XX:MaxMetaspaceSize=192m","-XX:MaxDirectMemorySize=256m","--add-opens","java.base/java.lang=ALL-UNNAMED","--add-opens","java.base/java.lang.reflect=ALL-UNNAMED","-Djava.security.egd=file:/dev/./urandom","-jar","app.jar"] 字节码多的换参数 ENTRYPOINT ["java","-Xms512m","-Xmx1024m","-XX:+UseContainerSupport","-XX:MaxRAMPercentage=60","-XX:MaxMetaspaceSize=300m","-XX:MaxDirectMemorySize=512m","--add-opens","java.base/java.lang=ALL-UNNAMED","--add-opens","java.base/java.lang.reflect=ALL-UNNAMED","-Djava.security.egd=file:/dev/./urandom","-jar","app.jar"]❗ 注意
MaxRAMPercentage仅 JDK10+- Java8 不支持,会直接报错
- docker run 命令后要添加: --memory=1g --memory-swap=1g
3️⃣ JVM + Docker 配合原则
JVM Xmx + Metaspace + DirectMemory ≤ Docker limit🎯 推荐配置(稳定版)
Docker: 1G JVM: 768M🧠 四、Linux 内存机制优化
1️⃣ 查看内存
free -h2️⃣ 清理缓存(临时)
sync; echo 3 > /proc/sys/vm/drop_caches⚠️ 不建议频繁使用
3️⃣ swappiness 优化
echo "vm.swappiness = 10" >> /etc/sysctl.conf sysctl -p👉 含义:
- 60(默认)→ 过早使用 swap ❌
- 10 → 只在必要时使用 ✔
💾 五、Swap 设置(重点)
1️⃣ 创建 swap(推荐放大盘)
dd if=/dev/zero of=/data/swapfile bs=1G count=162️⃣ 设置权限
chmod 600 /data/swapfile3️⃣ 格式化 swap
mkswap /data/swapfile4️⃣ 启用 swap
swapon /data/swapfile5️⃣ 开机自动挂载
echo '/data/swapfile swap swap defaults 0 0' >> /etc/fstab6️⃣ 查看 swap
free -h swapon --show🎯 Swap 作用
- 防止 JVM 瞬时 OOM
- 防止 Docker 被 kill
- 提供“缓冲区”
⚠️ 注意
- swap ≠ 内存扩容
- swap = 防崩溃缓冲
🧩 六、完整优化流程(实战顺序)
✔ Step 1:查内存
docker stats --no-stream✔ Step 2:定位 Top 容器
sort -k2 -h -r✔ Step 3:限制 Docker
--memory=1g✔ Step 4:限制 JVM
-Xmx768m✔ Step 5:加 swap
/data/swapfile✔ Step 6:验证
free -h docker stats🚨 七、常见错误总结
❌ 错误1:只调 swap
→ 没用
❌ 错误2:只调 Docker
→ JVM 还是爆
❌ 错误3:只调 JVM
→ 容器还是可能被 kill
