Docker和DC/OS的JVM优化



我正在将裸露的金属Java应用程序(JAR JDK8)移至Docker容器和DC/OS。我注意到Dockers上的一个奇数,我们将-XMX设置为32 GIG并分配一个36 GOG Docker容器。每隔几个小时左右,该应用程序将在旧的内存分配中峰值,而GC将在尝试进行堆转储时陷入循环(最大CPU)。

我可以使用任何优化或可以使用的东西来看看为什么在1-5秒的间隔中,我们如此快速地峰值?我可能需要使用Docker和JVM知道任何陷阱?

我们正在使用默认GC

仅供将来参考:

我们正在使用JDK 8,似乎Oracle最近刚刚添加了一些用于使用Docker的实验标志。我相信这种情况可能是当GC分配线程时,它并不尊重Cgroup的Docker线程数。实验旗似乎固定了我们的"脱离铁路问题"

https://blogs.oracle.com/java-platform-group/java-se-support-for-docker-docker-cpu-and-memory-limits

通常,您希望避免使用> 30GB内存的巨型应用程序,并将您的应用程序分为较小的零件,如果您有可能使用DC/OS(例如DC/OS)使用容器平台。

通常,关于GC和堆尺寸:如果您的尺寸较大,则全GC可能需要很长时间。就我个人而言,我经历了完整的GC冻结长达一分钟或更长时间,堆尺寸与您提到的30GB的尺寸非常相似。

关于容器中的Java:JVM实际上需要比使用-Xmx配置更多的内存。因此,如果您在DC/OS(马拉松)应用程序中指定2GB的内存限制,则无法设置-Xmx2G,因为此内存限制是一个严格的限制。如果您在容器内部的过程将超过这些内存限制,则将杀死容器。通过与配置的-Xmx相比,JVM保留更多的临时内存,这确实可能发生。通常,我建议将您配置的内存的75%用作-Xmx的值。

您可以查看支持-XX:+UseCGroupMemoryLimits的新版本。这是使用CGROUP容器限制进行内存消耗的JRE标志,请参见https://developers.redhat.com/blog/2017/04/04/openjdk-and-containers/有关更多信息。

最新更新