docker中的Java进程消耗的内存比指定的Xmx限制多

时间:2017-02-02 17:22:11

标签: java ubuntu memory memory-management docker

我在docker中运行java进程。我设置了xms(388m)和xmx(388m)。在应用程序启动后的某个时间,容器的内存消耗超过并达到大多数〜主机内存大小,并且容器被杀死。

  • 当我使用jprofiler连接到java进程时,我看到堆小于Xmx
  • 然而,容器内的top命令显示docker stats显示的内容
  • 当我在主机上运行相同的java进程时,它的内存使用量在Xmx边界内。

详细信息:

  1. Docker版本1.12.1,版本23cf638
  2. 主机操作系统:Ubuntu 14.04
  3. 容器图片:Ubuntu 14.04(也尝试使用Ubuntu 16.04)
  4. JRE:1.8.0_77(尝试1.8.0_112,1.8.0_121)(所有都是客户端JRE;我不能使用服务器JRE,因为这个应用程序需要JavaFX。我也使用单片机在无头模式下运行应用程序)
  5. Cmd

    java -server  -Djava.net.preferIPv4Stack =真  -Djavafx.monocle.headless =真  -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

  6. 我也尝试过多个论坛后设置MALLOC_ARENAS_MAX = 4(也尝试过2和1)。

    我还在运行docker容器时尝试设置--memory和--memory-reservation。在这种情况下,容器在达到内存限制时被终止。

    观察:在整个jvm的生命周期中,它使用的不到Xmx(388m)。但是docker stats继续增加并达到~1.2g(主机内存为2g),并且在某些时候会导致Java进程中出现OOM。所以我假设GC-freed-memory没有返回容器操作系统。

    感谢任何帮助。

    修改

    我错了。

    1. 即使在容器外面(当我在主机上运行时),jvm也消耗了相同数量的内存。 所以这不是docker的问题
    2. 容器内部和外部的最高命令结果是相同的。但是,探查器中显示的堆内存在范围内
    3. 该应用程序使用JavaFX webview创建大量短期线程。我相信这会导致堆栈增长(不确定是否有任何方法来衡量)。

1 个答案:

答案 0 :(得分:0)

我建议将资源限制在docker-container本身。如果您使用docker-compose运行容器,则可以使用 - resources 标记轻松完成。这样,docker容器从系统中获取的资源量就会受到限制。