为什么我的Java进程在docker容器与host之间消耗了两倍的内存

时间:2018-06-06 11:39:14

标签: java docker memory heap-memory

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

  1. Java应用程序是Jetty服务器9.4.9
  2. 上的Web应用程序
  3. Java版本:1.8
  4. 主持人:MAC
  5. Docker图片:jetty:9.4-jre8
  6. docker守护程序是18.03.1-ce版本。
  7. 在主机上我使用Yourkit工具分析内存消耗。

    对于泊坞窗容器docker stats <docker id/name>

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

    enter image description here

    然而,当我在容器上部署并运行相同的战争时,统计数据显示 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
    

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

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

    提前致谢

1 个答案:

答案 0 :(得分:1)

您可能希望尝试使用openJDK 8u212或更高的值再次进行测量(2019年4月16日)。 (自their license has changed起,没有Oracle JDK)

请参见Docker support in Java 8 — finally!中的“ Grzegorz Kocur”。
现在:

  

无需在Docker入口点使用任何棘手的解决方法,也无需将Xmx设置为固定值。

     

Docker支持也被反向移植到Java8。
  我们来检查一下标记为8u212的最新openjdk图像。我们将内存限制为1G,并使用1个CPU:

docker run -ti --cpus 1 -m 1G openjdk:8u212-jdk

您可以使用新标志(已在Java 10+中提供,但现在已移植回Java 8)和explained here来微调堆大小。

-XX:InitialRAMPercentage
-XX:MaxRAMPercentage
-XX:MinRAMPercentage
  

如果由于某种原因不希望新的JVM行为,可以使用-XX:-UseContainerSupport将其关闭。