有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

  1. Java应用程序是Jetty server 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上,我看到50米非堆大小+40米堆大小,总共~100米

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) 个答案

  1. # 1 楼答案

    您可能想再次尝试测量,使用openJDK 8u212或更多(2019年4月16日)。(没有Oracle JDK,因为their license has changed

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

    There is no need to use any hacky workarounds in a docker entrypoint, nor setting Xmx as fixed value anymore.

    Docker support was also backported to Java 8.
    Let’s check the newest openjdk image tagged as 8u212. We’ll limit the memory to 1G and use 1 CPU:

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

    您可以使用新的标志(已经出现在Java10+中,但现在已重新移植到Java8)和explained here微调堆大小

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

    If for some reason the new JVM behaviour is not desired it can be switched off using -XX:-UseContainerSupport.