我们如何提高低延迟系统的GC性能

时间:2019-03-20 11:43:25

标签: java tomcat garbage-collection

我们的Java后端系统正在运行tomcat和jdk1.8,最大的jvm大小为24g,系统延迟变得很长,并且cpu负载很高,在我们分析了GC日志后,我们发现GC的停顿很长,附带了一些快照在GCViewer中。 我们如何改善GC性能?

Chart

Event Details

Memory

Pause

Summary

2 个答案:

答案 0 :(得分:1)

在不了解您的应用程序的情况下,这里有一些一般性想法:

  • 您的应用程序似乎有很多长期使用的对象(仅收集了9g的长期使用的对象,剩下15gb),这会引起您的问题:虽然分配速度决定了GC暂停的频率,但它仍然是存在的时间确定GC暂停时间的对象(无法由GC释放的对象)。
  • 一个可能的原因可能是您的应用程序在某种程度上充当了内存数据库。也就是说,对象并非一直都需要,但不会写入数据库以保持对它们的快速内存访问。在这种情况下,您应该将它们以非堆方式存储(在不受GC管理的内存中)或使用内存数据库,例如Redis。这样,它们将以低延迟访问,但是GC不会考虑它们,因为无论如何都不会对其进行回收。
  • 另一种可能的解决方案是调整GC设置:您可以切换到G1,增加年轻一代的人数或提高晋升门槛;或这些的组合。增加年轻一代并减少晋升可能会导致终身制的增长大大减少,从而减少主要收藏的频率。切换到G1收集器将为您带来的好处是,该收集器仅可以考虑一些幸存者区域,并且可以将不朽物体留在单独的区域。

答案 1 :(得分:0)

很久以前,我为此主题写过guide。它仍然非常相关。

对于CMS垃圾收集器而言,调整大小最重要。看来您的年轻空间和旧空间都太小了。

旧空间应为活动集的大小(在完全GC后为〜堆大小)乘以某些因子。要凭经验找到因素,1.5是一个很好的起点。

只要您对年轻的GC暂停感到满意,则更大的年轻空间会更好。每个应用程序的年轻大小也很经验。

建议使用

-XX:InitiatingHeapOccupancyPercent=n-XX:+UseCMSInitiatingOccupancyOnly以确保并发周期及时启动。在某些情况下,-XX:CMSTriggerInterval=p也很有用。