我正在将一个简单的java应用程序(jar jdk8)转移到坞容器和DC/OS。我注意到码头工人有一个奇怪的模式,我们将-XMX设置为32 G,并分配一个36 gig码头集装箱。大约每隔几个小时,应用程序就会在旧的gen mem分配中激增,当它尝试进行堆转储时,GC将陷入一个循环(最大CPU)。
有什么优化或东西,我可以用来了解为什么在1-5秒的间隔,我们是如此之快?我可能需要了解Docker和JVM有什么问题吗?
我们使用默认的GC。
发布于 2017-09-06 19:39:05
供日后参考:
我们使用的是JDK 8,似乎Oracle最近刚刚为使用Docker添加了一些实验性标志。我相信情况可能是当GC分配线程时,它不尊重cgroup中的坞线程计数。实验用的旗帜似乎解决了我们的“越轨问题”。
https://blogs.oracle.com/java-platform-group/java-se-support-for-docker-cpu-and-memory-limits
发布于 2017-09-06 19:39:55
通常,如果您有可能使用DC/OS这样的容器平台,您希望避免内存大于30 DC的大型应用程序,并将应用程序划分为内存需求较少的较小部分。
一般来说,关于GC和堆大小:如果您有很大的堆大小,那么完整的GC可能需要很长的时间。就我个人而言,我经历了长达一分钟或更长时间的GC冻结,堆大小与您提到的30 GC非常相似。
容器中的Java : JVM实际上需要比用-Xmx配置的内存更多的内存。因此,如果在DC/OS (马拉松)应用程序中指定内存限制为2GB,则无法设置-Xmx2G,因为此内存限制是一个硬限制。如果容器内的进程将超过这些内存限制,则容器将被杀死。由于JVM将保留比配置的-Xmx更多的临时内存,这很有可能发生。通常,我建议使用您配置的内存的75%左右作为-Xmx的值。
您可以查看支持-XX:+UseCGroupMemoryLimits的较新的JRE版本。这是使用cgroup容器限制内存消耗的JRE标志,有关更多信息,请参见https://developers.redhat.com/blog/2017/04/04/openjdk-and-containers/。
https://stackoverflow.com/questions/46015451
复制相似问题