调整并行 GC 以实现高效的 Young GC

此图表显示了我们的 Java 应用程序在 4 天内的堆利用率 (OU+EU+S1U+S2U)。每一个 drop 都是一个 Young GC 事件。如您所见,堆使用量呈增长趋势。Full GC 在运行 6 天后发生(图中未显示)。它将堆使用率降低到正常水平,但暂停时间为 2 分钟,并导致应用程序丢弃许多事务。


http://img3.mukewang.com/616675b8000164d208490362.jpg

我们的 JRE 是 8,我们使用并行 GC。堆参数如下:

 java -server -Xms64g -Xmx64g -XX:MetaspaceSize=96M -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -XX:MaxMetaspaceSize=1g -XX:+UseParallelGC -XX:ParallelGCThreads=4 -XX:+HeapDumpOnOutOfMemoryError -Djava.net.preferIPv4Stack=true -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Dsun.zip.disableMemoryMapping=true

我试图了解什么调整可以使 Young GC 更有效,以便它删除所有垃圾并避免升级到老年代。


智慧大石
浏览 155回答 2
2回答

ibeautiful

问题似乎是对象被提升到永久空间然后死亡。减少这种情况的一种方法是使年轻空间更大,但这只会延迟完整收集。另一种方法可能是减少堆,使其收集更频繁,从而减少暂停时间。如果您使用 32GB 堆,它可以使用压缩 oops,从而提高内存使用效率。

九州编程

正如 Lawrey 先生指出的那样,您可以使年轻代变大,这将增加(希望如此)次要 GC 事件之间的时间。通过这样做,更多的对象应该成为垃圾,并将在次要 GC 中收集,而不是提升到旧的 gen。另一种方法是增加任期阈值,这与将对象在年轻代中保持更长时间的效果相同。另一个要问自己的问题是,你真的需要使用并行 GC 吗?如果使用 G1,一些收集旧空间的工作是与应用程序线程并发处理的。您可能能够完全消除长时间的停顿(假设您没有遭受过多的堆碎片),因为您不需要完整的压缩集合。为了完全消除停顿,我可以衷心推荐 Azul 的 Zing 中的 C4 收集器(我为他工作 :-))。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java