51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

好用的GC日志分析网站:https://gceasy.io/

为什么要介绍这个工具? {#%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E4%BB%8B%E7%BB%8D%E8%BF%99%E4%B8%AA%E5%B7%A5%E5%85%B7%EF%BC%9F}

GC日志是一个很重要的数据,它准确记录了每一次的GC的执行时间和执行结果,通过分析GC日志可以优化堆设置和GC设置,或者改进应用程序的对象分配模式。

GCEasy是什么? {#gceasy%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F}

业内首款借助机器学习技术引导的垃圾回收日志分析工具。GCeasy 内置有智能功能,可自动检测 JVM 和 Android GC 日志中的问题并推荐解决方案,推荐解决方案是付费功能。

GCEasy怎么使用?让我们来看个例子 {#gceasy%E6%80%8E%E4%B9%88%E4%BD%BF%E7%94%A8%EF%BC%9F%E8%AE%A9%E6%88%91%E4%BB%AC%E6%9D%A5%E7%9C%8B%E4%B8%AA%E4%BE%8B%E5%AD%90}

  1. 首先要开启应用GC日志,关于开启GC日志命令有很多可选参数,这里不细讲,可以参考:https://blog.csdn.net/lazycheerup/article/details/100917193
    本次使用以下命令演示:
    java -XX:+PrintGCDetails -Xloggc:/opt/ard-user-gc-%t.log -jar spring-boot-demo-0.0.1-SNAPSHOT.jar
    image-1660542283245
    image-1660542660991
  2. 将应用产生的GC上传到https://gceasy.io/
    image-1659952009736
    点击"分析",等待分析结果。
    image-1659952064755
  3. GC分析报告支持下载和分享连接。
    image-1659952125092

GC日志报告包含哪些指标分析? {#gc%E6%97%A5%E5%BF%97%E6%8A%A5%E5%91%8A%E5%8C%85%E5%90%AB%E5%93%AA%E4%BA%9B%E6%8C%87%E6%A0%87%E5%88%86%E6%9E%90%EF%BC%9F}

image-1659952222951
image-1659952271326
image-1659952322782
image-1659952331986
image-1659952341908
image-1659952354207
image-1659952362059
image-1659952369577
image-1659952376758
image-1659952384567

常见的一些GC问题 {#%E5%B8%B8%E8%A7%81%E7%9A%84%E4%B8%80%E4%BA%9Bgc%E9%97%AE%E9%A2%98}

对象过早晋升 {#%E5%AF%B9%E8%B1%A1%E8%BF%87%E6%97%A9%E6%99%8B%E5%8D%87}

一、现象:

  • 老年代使用率增长过快,每次Full GC后老年代使用率呈现断崖式下跌,Minor GC 和 Full GC都比较频繁。
  • 老年代空间占用量统计(通过gc日志统计):
    image-1660542880443
    二、影响:
  • Young GC 频繁,总的吞吐量下降。
  • Full GC 频繁,可能会有较大停顿。
    三、原因:
    年轻代(主要是eden区)过小:
  • eden区无法容纳足够多的年轻对象,造成young gc的次数增加。
  • 本应该在年轻代就回收的对象却晋升到了老年代,加快了老年代的占用速度,造成full gc的次数增加。
    四、优化:
  • 增大新生代空间,降低minor gc和major gc的频率,减少系统STW的时间、提高系统的吞吐量。

对象晋升失败 {#%E5%AF%B9%E8%B1%A1%E6%99%8B%E5%8D%87%E5%A4%B1%E8%B4%A5}

一、场景:

  • young gc过程中,To Survivor空间不足以放下eden + from Survivor中存活的对象,故这些存活的对象只能尝试着晋升到老年代中,若此时老年代的内存也不足以放下这些对象,则晋升失败(promotion failed),此时,老年代会进行full gc。
    二、优化:
  • 适当地调大Survivor空间,尽量避免朝生夕灭的对象进入老年代。
  • 使用标记整理算法收集,及时整理老年代中的内存碎片,避免因内存碎片太多导致大对象晋升失败:
  1. 开启老年代内存压缩:-XX:UseCMSCompactAtFullCollection
  2. 每次cms gc时都进行内存压缩:XX:CMSFullGCBeforeCompaction=0

并发收集失败 {#%E5%B9%B6%E5%8F%91%E6%94%B6%E9%9B%86%E5%A4%B1%E8%B4%A5}

一、场景:

  • 场景1:CMS GC期间,业务线程将对象放到老年代,若此时老年代空间不足,则会导致CMS并发收集失败(Concurrent Mode Failure)。
  • 场景2:CMS GC期间,若某次young gc过程中发生了promotion failed,则也会导致CMS并发收集失败。
  • CMS并发收集失败发生后,由于老年代空间不足,需要尽快回收老年代里面的不再被使用的对象,这时jvm会停止所有的应用线程,同时终止CMS收集,直接进行Serial Old来收集。
    二、现象:
  • stop the world持续时间比较长,系统持续(十几秒甚至几分钟)无响应。
    三、优化:
  • 在业务低峰时段提前触发full gc。
    没有开启-XX:+DisableExplicitGC的前提下调用System.gc()就会发生FullGC
  • 降低触发CMS GC的阈值,保障老年代有足够的空间。
    开启根据阈值触发CMS GC开关:-XX:+UseCMSInitiatingOccupancyOnly
    设置触发CMS GC的阈值:-XX:CMSInitiatingOccupancyFraction=xx (默认是92)
赞(0)
未经允许不得转载:工具盒子 » 好用的GC日志分析网站:https://gceasy.io/