3分钟带你看懂 GC 日志!
------------------------------------------------------------------------------------
01、背景介绍
在之前的几篇文章中,我们介绍了 JVM 内部布局、对象的创建过程、运行期的相关优化手段、垃圾对象的回收算法以及垃圾收集器等相关知识。
那么如何分析当前虚拟机性能呢?其中 GC 日志起到至关重要的作用。
实际上,每种垃圾收集器都有它独立的日志格式,尽管如此,虚拟机为了方便用户阅读,将各个收集器的日志都维持在一定的共性状态。
下面我们一起来看看不同的垃圾收集器,相关的 GC 日志内容。
本文是基于 JDK 1.8 版本运行,可能不同的版本各个内存区域的名称略有不同,对知识的理解不会产生明显的误区。
02、触发GC时机
通常,GC 触发的条件有两种:
- 1.程序调用
System.gc
时可能会触发,此时会建议 JVM 进行垃圾回收,但不代表一定会进行 GC 动作; - 2.系统自身来决定 GC 触发的时机,比如年轻代空间不足、老年代空间不足等就会主动触发 GC 动作
以上两种行为都会产生 GC 日志。
03、GC日志
在介绍之前,我们先看一段代码,下文的 GC 日志都会基于这段代码来分析。
运行时加上-verbose:gc
参数,以便简要的查看程序的 GC 情况,运行后的输出结果如下!
以上代码是一段对象相互引用的场景,但是 JVM 还是将对象回收了,也应证了一点,HotSpot 虚拟机并不是通过引用计数法来判定对象是否存活的。
下面我们还是以上面的代码为例,设置不同的虚拟机参数,看看 GC 日志情况。
3.1、Serial 和 Serial Old 组合垃圾收集器
Serial 和 Serial Old 组合的垃圾收集器,可以在运行时设置如下参数来开启。
运行之后,输出结果如下!
各个参数描述介绍:
def new generation
:表示年轻代的内存使用情况,其中eden space
表示Eden
空间的内存使用情况;from space
表示From Survivor
空间的内存使用情况;to space
表示To Survivor
空间的内存使用情况;tenured generation
:表示老年代的内存使用情况Metaspace
:表示元空间的内存使用情况,在 JDK1.7 中称为永久代
3.2、ParNew 和 Serial Old 组合垃圾收集器
ParNew 和 Serial Old 组合的垃圾收集器,可以在运行时设置如下参数来开启。
运行之后,输出结果如下!
其中par new generation
表示年轻代的内存使用情况,其它表达的内容与上相同。
3.3、Parallel Scavenge 和 Parallel Old 组合垃圾收集器
Parallel Scavenge 和 Parallel Old 组合的垃圾收集器,可以在运行时设置如下参数来开启。
需要注意的是,在 jdk1.8 及之后的版本中,-XX:+UseParallelGC和-XX:+UseParallelOldGC参数效果是一样的,都是用的 Parallel Old 作为老年代收集器;而在 jdk1.7 及之后的版本中,-XX:+UseParallelGC参数用的是 Serial Old 作为老年代收集器。
运行之后,输出结果如下!
3.4、ParNew 和 CMS + Serial Old 组合垃圾收集器
ParNew 和 CMS + Serial Old 组合的垃圾收集器,可以在运行时设置如下参数来开启。
运行之后,输出结果如下!
3.5、G1 垃圾收集器
G1 垃圾收集器,可以在运行时设置如下参数来开启。
运行之后,输出结果如下!
G1 收集器与以上收集器都不同,它会把整个 Java 堆分成若干个大小相等的独立区域,也是日志中的 Region,然后针对优先级高的 Region 区域进行收集。Region 区域可能存放的是年轻代的对象,也可能是老年代的对象。
04、小结
以上的日志输出,会发现很多的共性。
比如,以“GC”开头的,通常表示年轻代的收集情况;以“Full GC”开头的,表示整个堆的收集情况,其中带有“(System.gc()) ”信息的表示调用System.gc()
方法所触发的 GC。
以下面这个日志为例,来解读一下相关信息。
- 1.Full GC (System.gc()表示 Full GC 类型的 GC 动作,通过调用System.gc()方法而触发;
- 2.PSYoungGen: 496K->0K(38400K)表示年轻代 GC 前使用的容量为 496K,GC 后该内存区域使用的容量为 0K,年轻代总容量为 38400K;
- 3.ParOldGen: 8K->390K(87552K)表示老年代 GC 前使用的容量为 8K,GC 后该内存区域使用的容量为 390K,老年代总容量为 87552K;
- 4.504K->390K(125952K)表示整个堆 GC 前使用的容量为 504K,GC 后该内存区域使用的容量为 390K,整个堆总容量为 125952K;
- 5.Metaspace: 3008K->3008K(1056768K)表示元空间 GC 前使用的容量为 3008K,GC 后该内存区域使用的容量为 3008K,整个元空间总容量为 1056768K;
- 6.0.0045268 secs表示 Full GC 耗时为 0.0045268 秒;
- 7.Times: user=0.01 sys=0.00, real=0.00 secs表示 Full GC 期间用户的耗时、系统的耗时、实际操作的耗时,单位秒;
Heap 后面列举的是堆的内存使用情况。
本文主要围绕 GC 日志,进行了一次知识内容的整合和总结,内容比较多,如果有描述不对的地方,欢迎大家留言指出,不胜感激。
写到最后
最后感谢各位的阅读,原创不易,如果觉得文章写的不错,欢迎大家转发,点击【在看】让更多的人看到,谢谢大家的支持!
转自: https://mp.weixin.qq.com/s/1O8rxy-MFJg8Hhv2f8AvBA
----- 2024年8月30日09:20:37
-----full gc