当前位置 : 主页 > 手机开发 > harmonyos >

GC 玩起来(三)GC 日志分析

来源:互联网 收集:自由互联 发布时间:2023-08-25
摘要 GC 日志是判断 Java 应用程序内存是否存在故障的重要判断依据。《GC 玩起来》这个小系列,期望能够使零基础的读者快速理解 GC 相关的重要概念,最终掌握 GC 日志的分析方法。

摘要
GC 日志是判断 Java 应用程序内存是否存在故障的重要判断依据。《GC 玩起来》这个小系列,期望能够使零基础的读者快速理解 GC 相关的重要概念,最终掌握 GC 日志的分析方法。
第三篇《GC 日志分析》旨在介绍生成 GC 日志的相关 JVM 参数,如何读懂 GC 日志,以及如何借助图形化工具分析 GC 日志。

1 GC 日志能帮我们做什么

GC 日志是由 JVM 产生的对垃圾回收活动进行描述的日志文件。

通过 GC 日志,我们能够直观的看到内存回收的情况及过程,是能够快速判断内存是否存在故障的重要依据。

2 如何生成 GC 日志

在 JAVA 命令中增加 GC 相关的参数,以生成 GC日志:

JVM 参数

参数说明

备注

-XX:+PrintGC

打印 GC 日志

-XX:+PrintGCDetails

打印详细的 GC 日志

配置此参数时,-XX:+PrintGC 可省略

-XX:+PrintGCTimeStamps

以基准形式记录时间(即启动后多少秒,如:21.148:)

默认的时间记录方式,可省略

-XX:+PrintGCDateStamps

以日期形式记录时间(如:2022-05-27T18:01:37.545+0800: 30.122:)

当以日期形式记录时间时,日期后其实还带有基准形式的时间

-XX:+PrintHeapAtGC

打印堆的详细信息

-Xloggc:gc.log

配置 GC 日志文件的路径

常用的选项组合:

java -Xms512m -Xmx2g -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log -jar xxx.jar

3 读懂 GC 日志

前文我们介绍了通过 -XX:+UseSerialGC-XX:+UseParallelGC (同 -XX:+UseParallelOldGC )、 -XX:+UseParNewGC-XX:+UseConcMarkSweepGC-XX:+UseG1GC 这些参数,来指定使用不同的垃圾回收器组合。不同的垃圾回收器所生成的 GC 日志也是有差异的,尤其是 CMS 、 G1 所生成的日志,会比 Serial 、Parallel 所生成的日志复杂许多。

这里我们以 JDK1.8 默认使用的 -XX:+UseParallelGC (即 Parallel Scavenge + Parallel Old )为例,讲解其 GC 日志。

3.1 开头部分的环境信息

GC 玩起来(三)GC 日志分析_Java

上图是 GC 日志的开头部分:

  1. 第 1 部分是 Java 环境信息:
  • Java HotSpot(TM) 64-Bit Server VM (25.144-b01) 是 JVM 版本信息;
  • linux-amd64 JRE (1.8.0_144-b01) 是 JDK 版本信息;
  1. 第 2 部分是服务器内存信息:
  • physical 32611948k(7181112k free) 是服务器物理内存总大小与空闲大小;
  • swap 67108860k(66625832k free) 是服务器 swap 交换区的总大小与空闲大小;
  1. 第 3 部分打印出与 GC 相关的 JVM 启动参数,其中:
  • -XX:InitialHeapSize=1073741824 -XX:MaxHeapSize=2147483648 指定了堆大小的初始化值与最大值;
  • -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps 为 GC 日志的相关设置;
  • -XX:+UseCompressedClassPointers -XX:+UseCompressedOops 开启了普通对象和类的指针压缩,能够提高内存性能
  • -XX:+UseParallelGC 则体现出 JDK1.8 默认使用的垃圾回收器。

3.2 Young GC

GC 玩起来(三)GC 日志分析_老年代_02

上图描述的是 Young GC 活动:

  1. 第 1 部分是日志时间:
  • 2022-06-01T11:10:59.126+0800: 是日期格式的时间;
  • 86.281: 是基准格式的时间,也就是应用启动后的 N 秒;
  1. 第 2 部分是 GC 的类型与发生 GC 的原因:
  • GC 表示当前 GC 类型为 Young GC ;
  • Allocation Failure 是发生 GC 的原因,这里是年轻代中没有足够的空间来存储新数据了;
  1. 第 3 部分是 GC 活动的详情:
  • [PSYoungGen: 639473K->35837K(649728K)] ,从左到右分别是新生代垃圾回收前的大小、新生代垃圾回收后的大小、新生代总大小;
  • 686696K->87816K(1671680K) ,中括号外的这三个数字,从左到右分别是堆垃圾回收前的大小、堆垃圾回收后的大小、堆总大小;
  • 0.0192314 secs 是本次新生代垃圾回收的耗时;
  1. 第 4 部分是 GC 耗时的详情:
  • user=0.10 是用户耗时(即应用耗时);
  • sys=0.00 是系统内核耗时;
  • real=0.01 是实际耗时,由于多核的原因,实际耗时可能会小于用户耗时 + 系统耗时。

3.3 Full GC

GC 玩起来(三)GC 日志分析_Java_03

上图描述的是 Full GC 活动:

  1. 第 1 部分是日志时间,与 Minor GC 日志相同,不再赘述;
  2. 第 2 部分是 GC 的类型与发生 GC 的原因:
  • Full GC 表示当前 GC 类型为 Full GC ;
  • Metadata GC Threshold 是发生 GC 的原因,这里是元空间的占用大小达到了 GC 阈值;
  1. 第 3 部分是 GC 活动的详情:
  • [PSYoungGen: 33776K->0K(647680K)] ,从左到右分别是新生代垃圾回收前的大小、新生代垃圾回收后的大小、新生代总大小;
  • [ParOldGen: 51986K->59081K(1324544K)] ,从左到右分别是老年代垃圾回收前的大小、老年代垃圾回收后的大小、老年代总大小;
  • 85762K->59081K(1972224K) ,中括号外的这三个数字,从左到右分别是堆垃圾回收前的大小、堆垃圾回收后的大小、堆总大小;
  • [Metaspace: 92860K->92312K(1134592K)] ,从左到右分别是元空间垃圾回收前的大小、元空间垃圾回收后的大小、元空间总大小;
  • 0.1185325 secs 是本次新生代垃圾回收的耗时;
  1. 第 4 部分是 GC 耗时的详情,与 Minor GC 日志相同,不再赘述。

以上便是 JDK1.8 下 -XX:+UseParallelGC (即 Parallel Scavenge + Parallel Old )模式下, GC 日志的详细解读。不同的模式下的日志,对于新生代、老年代的别称也是不同的,我们将上一篇文章中的一张特征信息总结表格拿过来,再次加深一下印象:

JVM 参数

日志中对新生代的别称

日志中对老年代的别称

-XX:+UseSerialGC

DefNew

Tenured

-XX:+UseParallelGC

PSYoungGen

ParOldGen

-XX:+UseParallelOldGC

PSYoungGen

ParOldGen

-XX:+UseParNewGC

ParNew

Tenured

-XX:+UseConcMarkSweepGC

ParNew

CMS

-XX:+UseG1GC

没有专门的新生代描绘,有 Eden 和 Survivors

没有专门的老年代描绘,有 Heap

4 GC 日志的图形化分析工具

接下来我们需要配合一些图形化的工具来分析 GC 日志。

4.1 GCeasy

GCeasy 是笔者最为推荐的 GC 日志分析工具,它是一个在线工具,号称业界第一个以机器学习算法为基础的 GC 日志分析工具。它不仅能够生成多元化的分析图例(这是免费的),还能够推荐 JVM 配置、提出存在的内存问题并推荐对应的解决方案(后面这些功能是付费的)。

我们来看一下免费的功能:

  • 内存统计,包含新生代、老年代、持久代的最大分配值与峰值:

GC 玩起来(三)GC 日志分析_JVM_04

  • 关键性能指标统计,包含吞吐量、应用暂停时间(含平均暂停时间、最大暂停时间、按暂停时间范围统计 GC 次数):

GC 玩起来(三)GC 日志分析_垃圾回收_05

  • 多元化的图例,包含 GC 前后的堆的大小、 GC 分布、回收空间情况、新生代/老年代/持久代的内存情况、新生代向持久代转化情况:

GC 玩起来(三)GC 日志分析_垃圾回收_06

  • GC 详细数据统计:

GC 玩起来(三)GC 日志分析_垃圾回收_07

4.2 GCViewer

GCViewer 是一个离线的 GC 可视化分析工具,在同类离线工具中,可以说是功能最为强大的了。下载地址:github.com/chewiebug/G…

  • GCViewer 提供了一个交互式的图例区,可以根据个人需要来展示所选择的指标:

GC 玩起来(三)GC 日志分析_JVM_08

  • GCViewer 对于数据的统计也是相当之完善的:

GC 玩起来(三)GC 日志分析_Java_09

GC 玩起来(三)GC 日志分析_JVM_10

4.3 GChisto

GChisto 也是一个离线工具,功能相较于 GCViewer 显得比较简单,下载地址:github.com/jewes/gchis…

  • GC 数据统计,包含各类 GC 的次数、耗时、开销占比等:

GC 玩起来(三)GC 日志分析_JVM_11

  • 提供 GC 不同时间范围内次数统计、耗时统计等图例:

GC 玩起来(三)GC 日志分析_老年代_12

GC 玩起来(三)GC 日志分析_JVM_13

4.4 GCLogViewer

GCLogViewer 也是一个离线工具,官方地址国内无法打开(code.google.com/p/gclogview…),想要下载的话可以到 CSDN 上找一找。

其功能与 GChisto 比较相似,效果图如下:

GC 玩起来(三)GC 日志分析_JVM_14

GC 玩起来(三)GC 日志分析_老年代_15

网友评论