简体   繁体   English

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

[英]Why does my Java process consumes twice memory inside a docker container vs host

I faced an interesting problem trying to analyze a memory consumption in my Java application running on docker container vs host machine. 我在尝试分析在docker容器与主机上运行的Java应用程序中的内存消耗时遇到了一个有趣的问题。

  1. The Java app is web app on the Jetty server 9.4.9 Java应用程序是Jetty服务器9.4.9上的Web应用程序
  2. Java version : 1.8 Java版本:1.8
  3. Host : MAC 主持人:MAC
  4. Docker images: jetty:9.4-jre8 Docker图像:jetty:9.4-jre8
  5. The docker daemon is 18.03.1-ce version. docker守护程序是18.03.1-ce版本。

On the host I'm using Yourkit tool to analyze a memory consumption. 在主机上,我正在使用Yourkit工具来分析内存消耗。

For docker container docker stats <docker id/name> 对于docker container docker stats <docker id/name>

What I'm getting is that on MAC yourkit shows me 50M Non-heap size + ~40M heap size, in total ~ 100M 我得到的是,在你的MAC上你显示50M非堆大小+ 40M堆大小,总共~ 100M

在此输入图像描述

Whereas, when I deploy and run the same war on a container, the stats shows me 200M 然而,当我在容器上部署并运行相同的战争时,统计数据显示我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

Can anyone shed some light on this phenomenon? 任何人都可以对这一现象有所了解吗?

Assuming that stats provides wrong results, I tried to limit the memory on a container using --memory flag doesn't help much, I'm getting OOM. 假设stats提供了错误的结果,我试图使用--memory标志来限制容器上的内存并没有多大帮助,我得到了OOM。

Thanks in advance 提前致谢

You might want to try and measure again, with an openJDK 8u212 or more (April, 16th 2019). 您可能想尝试再次测量,使用openJDK 8u212或更多(2019年4月16日)。 (no Oracle JDK, since their license has changed ) (没有Oracle JDK,因为他们的许可证已经更改

See " Docker support in Java 8 — finally! " from Grzegorz Kocur . 请参阅Grzegorz Kocur的Java 8中的Docker支持 - 终于! ”。
Now: 现在:

There is no need to use any hacky workarounds in a docker entrypoint, nor setting Xmx as fixed value anymore. 无需在docker入口点中使用任何hacky变通办法,也不需要将Xmx设置为固定值。

Docker support was also backported to Java 8. Docker支持也被移植到Java 8。
Let's check the newest openjdk image tagged as 8u212. 让我们检查标记为8u212的最新openjdk图像。 We'll limit the memory to 1G and use 1 CPU: 我们将内存限制为1G并使用1个CPU:

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

You can fine-tune the heap-size with new flags (already present in Java 10+, but now back ported to Java 8), and explained here . 您可以使用新标志(已经存在于Java 10+中,但现在已经移植到Java 8)来微调堆大小,并在此处进行解释

-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 . 如果由于某种原因不希望新的JVM行为,可以使用XX:-UseContainerSupport关闭它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM