【发布时间】:2017-06-19 21:28:37
【问题描述】:
我在 docker 中运行一个 java 进程。我已经设置了 xms(388m) 和 xmx(388m)。应用程序启动后的某个时间,容器的内存消耗超过并达到最大~主机内存大小,容器被杀死。
- 当我使用 jprofiler 连接到 java 进程时,我看到堆小于 Xmx
- 但是容器内的 top 命令显示
docker stats显示的内容 - 当我在主机上运行相同的 java 进程时,它的内存使用量在 Xmx 边界内。
详情:
- Docker 版本 1.12.1,构建 23cf638
- 主机操作系统:Ubuntu 14.04
- 容器映像:Ubuntu 14.04(也尝试使用 Ubuntu 16.04)
- JRE: 1.8.0_77(也试过 1.8.0_112、1.8.0_121)(都是客户端 JRE;我不能使用服务器 JRE,因为这个应用程序需要 JavaFX。我也使用单片眼镜在无头模式下运行应用程序)李>
-
命令:
java -服务器 -Djava.net.preferIPv4Stack=true -Djavafx.monocle.headless=true -Dglass.platform=单片眼镜 -Dmonocle.platform=无头 -Dprism.order=sw -Djsse.enableSNIExtension=false -XX:+ExitOnOutOfMemoryError -XX:+HeapDumpOnOutOfMemoryError -Xms388m -Xmx388m -XX:MetaspaceSize=32m -XX:MaxMetaspaceSize=64m -jar myApp-1.0.jar
经过多个论坛后,我还尝试设置 MALLOC_ARENAS_MAX=4(也尝试使用 2 和 1)。
我还尝试在运行 docker 容器时设置 --memory 和 --memory-reservation。在这种情况下,容器会在达到内存限制时被杀死。
观察:在 jvm 的整个生命周期中,它使用的内存少于 Xmx (388m)。然而,docker stats 继续增加并达到 ~1.2g(主机内存为 2g),并且在某些时候会导致 java 进程中的 OOM。所以我假设 GC-freed-memory 没有返回容器操作系统。
感谢任何帮助。
编辑:
我错了。
- 即使在容器之外(当我在主机上运行时),jvm 也消耗了相同数量的内存。 所以这不是 docker 的问题
- 容器内外的top命令结果相同。然而,分析器中显示的堆内存在界限内
- 该应用程序使用 JavaFX webview,它创建了许多短期线程。我相信这会导致堆栈增长(不确定有什么方法可以衡量)。
【问题讨论】:
-
这可能与this question有关。
标签: java ubuntu memory memory-management docker