甲骨文 ARM 实例 Docker 内存占用过高,通常是因为容器未设置内存限制或 Java 应用堆栈配置不当。建议先通过 docker stats 定位高占用容器,再设置内存上限并配置 Swap 防止 OOM。
先说结论:先定位高占用进程,再限制容器资源,最后配置系统 Swap 作为缓冲。
- 先定位:使用 docker stats 找出内存占用最高的容器。
- 先做:为容器添加 `--memory` 参数限制最大可用内存。
- 再验证:观察 OOM 日志和 docker stats 确认不再触发杀进程。
命令速用版
# 查看容器实时内存占用
docker stats `--no-stream`
# 查看系统内存和 Swap 情况
free -h
# 临时限制运行中容器的内存上限(示例限制为 1GB)
docker update `--memory` 1g <容器 ID 或名称>
# 查看内核是否触发 OOM 杀进程
dmesg | grep -i "out of memory"为什么会这样
甲骨文 ARM 实例默认不开启 Swap 且 Docker 容器默认无内存上限,导致单个容器可能耗尽物理内存触发 OOM。
Linux 系统会将空闲内存用于文件缓存,free 命令显示的 used 内存包含缓存,容易误判为占用过高。Docker 容器如果不设置限制,内部应用(尤其是 Java)会尝试占用所有可见的物理内存。甲骨文 ARM 实例虽然提供免费额度,但物理内存总量固定,一旦容器超出限制,内核 OOM Killer 会强制终止进程。
分步处理
步骤 1:定位高占用容器
执行 docker stats `--no-stream` 查看当前所有容器的内存百分比。记录 MEM% 最高的容器名称。
步骤 2:设置容器内存限制
修改 Docker Compose 文件或启动命令,添加内存限制。例如限制容器最大使用 2GB 内存:
deploy:
resources:
limits:
memory: 2G如果是直接启动的命令,添加 -m 2G 参数。对于正在运行的容器,可使用 docker update `--memory` 2G <容器 ID> 即时生效。
步骤 3:配置系统 Swap 分区
甲骨文 ARM 实例默认通常无 Swap。在内存紧张时,创建 Swap 文件可防止系统直接崩溃。创建一个 2GB 的 Swap 文件:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab步骤 4:优化 Java 应用内存配置
如果运行的是 Java 应用,需限制 JVM 堆大小,避免 JVM 按容器可见内存全量分配。在启动参数中加入:
-XX:MaxRAMPercentage=75.0怎么验证是否生效
执行 docker stats 观察受限容器的 MEM% 是否稳定在设定值以下。检查 dmesg | grep -i oom 确认没有新的 OOM 杀进程记录。观察业务日志确认应用没有因内存不足频繁重启。
常见坑
- Swap 性能影响:Swap 使用磁盘模拟内存,频繁交换会导致 I/O 升高,仅作为防崩溃缓冲,不建议依赖 Swap 提升性能。
- Oracle Cloud Agent 占用:实例自带的监控代理会占用少量内存,计算可用内存时需预留这部分开销。
- 缓存误判:Linux 缓存占用高属于正常现象,只要 available 内存充足,无需刻意清理缓存。
常见问题
开启 Swap 会影响甲骨文实例性能吗?
频繁使用 Swap 会降低磁盘 I/O 性能,但能防止 OOM 崩溃。建议仅作为应急缓冲,主要靠限制容器内存解决问题。
为什么限制了内存容器还是被杀?
可能是限制值设置过小,或者 Java 应用未配置 MaxRAMPercentage 导致堆溢出。需调大限制或优化应用配置。
甲骨文 ARM 实例推荐分配多少内存给 Docker?
公开资料中没有看到可靠的量化数据,建议预留 10%-20% 给系统进程,剩余内存再分配给容器。