目录
- 一、引言
- 二、开启 GC 日志
- 三、解析 GC 日志
- 四、优化建议
一、引言
在 Java 应用程序的运行过程中,垃圾收集
(Garbage Collection,简称 GC)是一个非常重要的环节。GC 负责自动管理内存,回收不再使用的对象所占用的内存空间。为了了解 GC 的行为和性能,我们通常需要开启 JVM 的 GC 日志功能,收集并分析 GC 日志数据。
二、开启 GC 日志
Java 项目中,默认情况下 GC 日志功能是关闭的,有多种方法能够开启 GC 的日志功能,使用 -verbose:gc
或 -XX:+PrintGC
都能创建基本的 GC日志(这两个日志表示实际上互为别名) ,但是使用 -XX:+PrintGCDetails
标志会创建更详细的 GC 日志。
先提供一个比较通用的开启日志方式供参考:
java -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=14 -XX:GCLogFileSize=20M -XX:+PrintHeapAtGC -XX:+HeapDumpOnOutOfMemoryError -Xloggc:springboot-demo-gc-%t".log" -jar springboot-demo.jar
-XX:+PrintGCDetails
:打印更详细的 GC 日志信息,包括各个内存区域的使用情况、GC 的触发原因等。-XX:+PrintGCTimeStamps
:打印 GC 发生的时间戳。(以基准时间的形式)-XX:+PrintGCDateStamps
:打印 GC 发生的时间戳。(以标准时间的形式,如:2024-04-13T17:35:04.859+0800)-XX:+UseGCLogFileRotation
:启用 GC 日志文件的自动轮转功能,维持日志目录中的日志文件在一定的数目。-XX:NumberOfGCLogFiles=14
:GC 日志文件的滚动数量,使 GC 日志文件数量维持在 14 个,超出 14 个后,将日志覆盖写入到最早的日志文件中。-XX:GCLogFileSize=20M
:GC 日志文件的大小,超出大小后触发日志的轮转,将日志覆盖写入到最早的日志文件中。-XX:+PrintHeapAtGC
:在进行 GC 的前后打印出堆的信息。-XX:+HeapDumpOnOutOfMemoryError
:内存溢出的时候生成 dump 文件。-XX:HeapDumpPath=目录/xxx.hprof
:指定内存溢出时,dump 文件的生成路径,默认为当前目录。-Xloggc:springboot-demo-gc-%t".log"
:指定 GC 日志的输出文件。
三、解析 GC 日志
在解析 GC 日志前,推荐一个在线解析 GC 日志的地址,我个人感觉比较好用:
- GCeasy: https://gceasy.ycrash.cn/
当然,我们也可以完全自己进行分析。
GC 日志的格式和内容可以因 JVM 版本和 GC 算法的不同而会有所差异。下面是一个典型的 GC 日志示例:
2023-04-25T10:30:00.123+0800: 1.234: [GC (Allocation Failure) [PSYoungGen: 123456K->12345K(153600K)] 185432K->67890K(579200K), 0.0123456 secs] [Times: user=0.009876, sys=0.002468, real=0.012345]
2023-04-25T10:30:00.123+0800
:在2023年4月25日10点30分00.123秒(UTC+8时区)时,发生了一次GC。[PSYoungGen: 123456K->12345K(153600K)]
:GC前,新生代(PSYoungGen)使用了123456K内存,GC后减少到12345K。185432K->67890K(579200K), 0.0123456 secs
:整个堆内存(包括老年代和新生代)GC前使用了185432K,GC后减少到67890K。GC持续了0.0123456秒。[Times: user=0.009876, sys=0.002468, real=0.012345]
:用户态CPU时间为0.009876秒,内核态CPU时间为0.002468秒,实际耗时为0.012345秒,最后这个是最重要的考察维度。
通过解析GC日志,我们可以了解GC的频率、持续时间、回收的内存量等信息,从而分析应用程序的内存使用情况和性能瓶颈。
四、优化建议
根据 GC 日志的分析结果,我们可以采取一些优化措施来提高应用程式的性能:
- 调整堆内存大小: 根据应用程序的实际需求,适当增加或减少堆内存的大小。
- 选择合适的 GC 算法: 不同的 GC 算法适用于不同的应用场景。根据 GC 日志的分析结果,选择最适合当前应用程序的 GC 算法。
- 优化代码: 减少对象的创建和长时间持有,避免内存泄漏等问题。
- 使用内存分析工具: 结合内存分析工具(如)
整理完毕,完结撒花~🌻
参考地址:
1.深入解析Java日志:如何开启JVM GC日志获取,https://developer.baidu.com/article/details/3210478
2.JVM 配置GC日志,https://blog.csdn.net/Coco_chun/article/details/120332428
3.【Java8】jvm 开启GC日志(ParNew+CMS),https://blog.csdn.net/smallbirdnq/article/details/132906468