1. GC日志格式
1.1 复习:GC分类
新生代收集:当Eden区满的时候就会进行新生代收集,所以新生代收集和S0区域和S1区域无关
老年代收集和新生代收集的关系:进行老年代收集之前会先进行一次年轻代的垃圾收集,原因如下:一个比较大的对象无法放入新生代,那它自然会往老年代去放,如果老年代也放不下,那会先进行一次新生代的垃圾收集,之后尝试往新生代放,如果还是放不下,才会进行老年代的垃圾收集,之后在往老年代去放,这是一个过程,我来说明一下为什么需要往老年代放,但是放不下,而进行新生代垃圾收集的原因,这是因为新生代垃圾收集比老年代垃圾收集更加简单,这样做可以节省性能
进行垃圾收集的时候,堆包含新生代、老年代、元空间/永久代:可以看出Heap后面包含着新生代、老年代、元空间,但是我们设置堆空间大小的时候设置的只是新生代、老年代而已,元空间是分开设置的
1.1.1 哪些情况会触发Full GC:
- 老年代空间不足
- 方法区空间不足
- 显示调用System.gc()
- Minior GC进入老年代的数据的平均大小大于老年代的可用内存
- 大对象直接进入老年代,而老年代的可用空间不足
1.2 GC日志分类
1.2.1 MinorGC
1.2.2 FullGC
1.3 GC日志结构剖析
1.3.1 垃圾回收器
1.3.2 GC前后情况
1.3.3 GC时间
1.4 Minor GC日志解析
日志数据:
2020-11-20T17:19:43.265-0800
:添加-XX:+PrintGCDateStamps参数。日志打印时间 日期格式 如2013-05-04T21:53:59.234+08000.822
:添加-XX:+PrintGCTimeStamps该参数gc发生时,Java虚拟机启动以来经过的秒数[GC(Allocation Failure)
:发生了一次垃圾回收,这是一次Minior GC。它不区分新生代还是老年代GC,括号里的内容是gc发生的原因,这里的Allocation Failure的原因是新生代中没有足够区域能够存放需要分配的数据而失败[PSYoungGen:76800K->8433K(89600K)
:PSYoungGen
:表示GC发生的区域,区域名称与使用的GC收集器是密切相关的- Serial收集器:Default New Generation 显示Defnew
- ParNew收集器:ParNew
- Parallel Scanvenge收集器:PSYoung
- 老年代和新生代同理,也是和收集器名称相关
76800K->8433K(89600K)
:GC前该内存区域已使用容量->GC后盖区域容量(该区域总容量)- 如果是新生代,总容量则会显示整个新生代内存的9/10,即eden+from/to区
- 如果是老年代,总容量则是全身内存大小,无变化
76800K->8449K(294400K)
:虽然本次是Minor GC,只会进行新生代的垃圾收集,但是也肯定会打印堆中总容量相关信息。在显示完区域容量GC的情况之后,会接着显示整个堆内存区域的GC情况:GC前堆内存已使用容量->GC后堆内存容量(堆内存总容量),并且堆内存总容量 = 9/10 新生代 + 老年代,然后堆内存总容量肯定小于初始化的内存大小,0.0088371
:整个GC所花费的时间,单位是秒[Times:user=0.02 sys=0.01,real=0.01 secs]
- user:指CPU工作在用户态所花费的时间
- sys:指CPU工作在内核态所花费的时间
- real:指在此次事件中所花费的总时间
1.5 Full GC日志解析
日志数据:
2020-11-20T17:19:43.794-0800
:添加-XX:+PrintGCDateStamps参数日志打印。时间 日期格式 如2013-05-04T21:53:59.234+08001.351
:添加-XX:+PrintGCTimeStamps该参数。gc发生时,Java虚拟机启动以来经过的秒数Full GC(Metadata GCThreshold)
:发生了一次垃圾回收,这是一次Full GC。它不区分新生代GC还是老年代GC。括号中是gc发生的原因,原因:Metaspace区不够用了。除此之外,还有另外两种情况会引起Full GC,如下:Full GC(FErgonomics)
:原因:JVM自适应调整导致的GCFull GC(System)
:原因:调用了System.gc()方法
[PSYoungGen: 100082K->0K(89600K)]
:PSYoungGen
:表示GC发生的区域,区域名称与使用的GC收集器是密切相关的:- Serial收集器:Default New Generation 显示DefNew
- ParNew收集器:ParNew
- Parallel Scanvenge收集器:PSYoungGen
- 老年代和新生代同理,也是和收集器名称相关
10082K->0K(89600K)
:GC前该内存区域已使用容量->GC该区域容量(该区域总容量)- 如果是新生代,总容量会显示整个新生代内存的9/10,即eden+from/to区
- 如果是老年代,总容量则是全部内存大小,无变化
ParOldGen:32K->9638K(204800K)
:老年代区域没有发生GC,因此本次GC是metaspace引起的10114K->9638K(294400K)
:在显示完区域容量GC的情况之后,会接着显示整个堆内存区域的GC情况:GC前堆内存已使用容量->GC后堆内存容量(堆内存总容量),并且堆内存总容量 = 9/10 新生代 + 老年代,然后堆内存总容量肯定小于初始化的内存大小[Meatspace:20158K->20156K(1067008K)]
:metaspace GC 回收2K空间,0.0285388
:整个GC所花费的时间,单位是秒[Times:user=0.11 sys=0.00,real=0.03 secs]
- user:指CPU工作在用户态所花费的时间
- sys:指CPU工作在内核态所花费的时间
- real:指在此次事件中所花费的总时间
2. GC日志分析工具
略,看视频