【问题标题】:How can we improve the GC performance for low latency system我们如何提高低延迟系统的 GC 性能
【发布时间】:2019-08-11 02:24:40
【问题描述】:

我们的java后端系统运行tomcat和jdk1.8,最大jvm大小为24g,系统延迟变长,cpu负载高,分析GC日志后发现GC停顿时间较长,附上一些快照在 GCViewer 中。 我们如何提高 GC 性能?

【问题讨论】:

  • 你有没有尝试过?网上有大量关于如何调整 GC 的信息。它通常需要有条不紊的、渐进的方法。您不能只期望在这里转储一些指标,然后让我们说“是的,您忘记了 -XXgoReallyFast 标志”
  • 您手头没有任何监控工具可以将诊断结果复制为文本而不是屏幕截图吗?还是只记录文件?
  • 您遇到并发模式故障,您可能想要提高最大堆大小。或者您可以尝试升级到 java 12 并尝试其中一种实验性的低暂停收集器(shenandoah,ZGC)

标签: java tomcat garbage-collection


【解决方案1】:

很久以前我已经为那个话题写了guide。它仍然非常相关。

对于 CMS 垃圾收集器来说,最重要的是调整大小。看来你的年轻和年老的空间都太小了。

旧空间应该是您的活动集的大小(~ 完全 GC 后的堆大小)乘以某个因子。系数需要凭经验找到,1.5 是一个很好的起点。

只要年轻 GC 暂停没有问题,更大的年轻空间会更好。每个应用程序的年轻大小也非常具有经验性。

推荐-XX:InitiatingHeapOccupancyPercent=n-XX:+UseCMSInitiatingOccupancyOnly保证并发循环及时启动。在某些情况下-XX:CMSTriggerInterval=p 也很有用。

【讨论】:

    【解决方案2】:

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

    • 您的应用程序似乎有大量的长寿命对象(只有 9gb 的老年代被收集,剩下 15gb),这会导致您的问题:虽然分配速度决定了 GC 暂停的频率,但它是生活量决定 GC 暂停时长的对象(不能被 GC 释放)。
    • 一个可能的原因是您的应用程序在某种程度上充当了内存数据库。也就是说,对象并非一直都需要,但不会写入数据库以保持对它们的快速内存访问。在这种情况下,您应该将它们存储在堆外(在不受 GC 管理的内存中)或使用内存数据库,例如雷迪斯。这样,它们可以以低延迟访问,但不会被 GC 考虑,因为它们无论如何都不会被回收。
    • 另一个可能的解决方案可能是调整您的 GC 设置:您可以切换到 G1,增加年轻代的大小或提高提升阈值;或这些的组合。增加年轻代和减少提升可能会导致终身代的增长减少,从而减少主要收集的频率。切换到 G1 收集器会给您带来好处,即此收集器只能考虑一些幸存区域,并且可以只留下不朽对象的区域。

    【讨论】:

    • 非常好的点,我们的新生代NewSize非常小(600M),我会增加它更大,它可能会有所帮助。
    • 增加年轻代后问题解决
    猜你喜欢
    • 2015-03-19
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    相关资源
    最近更新 更多