为什么我的 Java 进程在 docker 容器和主机中消耗了两倍的内存

Den*_*hin 7 java memory heap-memory docker

我在尝试分析在 docker 容器与主机上运行的 Java 应用程序中的内存消耗时遇到了一个有趣的问题。

  1. Java 应用程序是 Jetty 服务器 9.4.9 上的 Web 应用程序
  2. Java 版本:1.8
  3. 主机:MAC
  4. Docker 镜像:jetty:9.4-jre8
  5. docker 守护进程是 18.03.1-ce 版本。

在主机上,我使用 Yourkit 工具来分析内存消耗。

对于 docker 容器 docker stats <docker id/name>

我得到的是,在 MAC yourkit 上显示了 50M 非堆大小 + ~40M 堆大小,总共 ~ 100M

在此处输入图片说明

然而,当我在容器上部署和运行相同的战争时,统计数据显示为200M

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %               NET I/O             BLOCK I/O           PIDS
879fb113ca8d        jetty-app           0.19%               214.6MiB / 1.952GiB   10.74%              1.49MB / 88.9kB     31.7MB / 6.42MB     29
Run Code Online (Sandbox Code Playgroud)

任何人都可以对这种现象有所了解吗?

假设stats提供了错误的结果,我尝试使用--memory标志限制容器上的内存没有多大帮助,我得到了 OOM。

提前致谢

Von*_*onC 3

您可能想使用openJDK 8u212或更高版本再次尝试测量(2019 年 4 月 16 日)。(没有 Oracle JDK,因为他们的许可证已更改

\n\n

请参阅Grzegorz Kocur的“ Java 8\xe2\x80\x8a\xe2\x80\x94\xe2\x80\x8afinally 中的 Docker 支持! ” 。\n现在:

\n\n
\n

无需在 docker 入口点中使用任何 hacky 解决方法,也无需再将 Xmx 设置为固定值。

\n\n

Docker 支持也向后移植到 Java 8。
\n 让\xe2\x80\x99s 检查标记为 8u212 的最新 openjdk 映像。我们\xe2\x80\x99将内存限制为1G并使用1个CPU:

\n\n
docker run -ti --cpus 1 -m 1G openjdk:8u212-jdk\n
Run Code Online (Sandbox Code Playgroud)\n
\n\n

您可以使用新标志(已存在于 Java 10+ 中,但现在向后移植到 Java 8)来微调堆大小,并在此处进行了解释

\n\n
-XX:InitialRAMPercentage\n-XX:MaxRAMPercentage\n-XX:MinRAMPercentage\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

如果由于某种原因不需要新的 JVM 行为,可以使用 - 关闭它XX:-UseContainerSupport

\n
\n