天呐!他工作三年还看不懂GC日志

1、在idea中配置VM参数

-verbose:gc # 在控制台输出GC情况
-XX:+UseSerialGC # 使用Serial垃圾回收器
-Xms20M # 最小堆 20M
-Xmx20M # 最大堆 20M
-Xmn10M # 年轻代 10M
-XX:+PrintGCDetails # 打印GC日志细节
-XX:SurvivorRatio=8 # eden:survivor比值=8:1

在这里插入图片描述

VM虚拟机参数说明:

分配最小堆 20M,最大堆 20M,年轻代 10M,eden:survivor比值=8:1,所以eden区域 8M,from区域 1M,to区域 1M;老年代 10M。

2、编写测试代码


/**
 * VM参数:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
 *
 * 10M新生代,eden:survivor 比例 8:1,所以eden 8192K,from:1024K,to:1024K
 * 分配完allocation1,allocation2,allocation3之后,剩余空间不够分配allocation4,会发生MinorGC:PSYoungGen: 7052K->873K(9216K)]
 * 新生代从7052K-》873K,
 *
 * 老年代10M,使用4MB,allocation4 分配到老年代(大对象或者是分配担保机制)
 *
 * @Date: 2021/3/31 21:09
 */
public class TestMinorGC {

    private static final int _1MB = 1024 * 1024;

    public static void main(String[] args) {
        byte[] allocation1, allocation2, allocation3, allocation4;

        allocation1 = new byte[2 * _1MB];
        allocation2 = new byte[2 * _1MB];
        allocation3 = new byte[2 * _1MB];
        allocation4 = new byte[4 * _1MB];
    }
}

测试代码分配 4 个对象,allocation1、allocation2、allocation3空间2M,allocation4 空间4M。

这样的话,eden区域只有 8M,分配完allocation1、allocation2、allocation3,再分配allocation4空间就不够了,会触发MinorGC。

3、执行main方法输出

[GC (Allocation Failure) [PSYoungGen: 7054K->882K(9216K)] 7054K->4986K(19456K), 0.0036974 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 9216K, used 7265K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 8192K, 77% used [0x00000007bf600000,0x00000007bfc3b958,0x00000007bfe00000)
  from space 1024K, 86% used [0x00000007bfe00000,0x00000007bfedcb20,0x00000007bff00000)
  to   space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
 ParOldGen       total 10240K, used 4104K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  object space 10240K, 40% used [0x00000007bec00000,0x00000007bf002020,0x00000007bf600000)
 Metaspace       used 3217K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 355K, capacity 388K, committed 512K, reserved 1048576K

理解GC日志:

1、GC (Allocation Failure) 标示发生了 GC,如果出现 “FuLL GC“ 则表示这次GC发生了STW(stop the word),这里是GC,表示没有STW。

2、PSYoungGen:表示GC发生的区域为新生代,不同的垃圾回收器,这里的名称不一样,这里是 PSYoungGen 表示垃圾回收器是 Parallel Scavenge 收集器。

3、7054K->882K(9216K):表示新生代,“该区域GC发生前已使用容量->该区域GC发生后使用容量(该内容区域总容量)”。发生MinorGC,新生代空间从7054K到了882K。说明把allocation1、allocation2、allocation3都回收掉了。

在这里插入图片描述

4、7054K->4986K(19456K):表示Java堆总容量,“java堆GC发生前已使用容量->java堆GC发生后已使用容量(java堆总容量);说明回收之前,堆中存在allocation1、allocation2、allocation3三个对象,回收之后只有allocation4对象。

在MinorGC之前,堆中总共有三个对象allocation1、allocation2、allocation3,占用空间6.88M

在这里插入图片描述

在MinorGC之后,堆中共有1个对象,allocation4,占用4.88M

在这里插入图片描述

5、[Times: user=0.00 sys=0.00, real=0.00 secs] 用户态消耗CPU时间;内核态消耗CPU时间;操作从开始到结束的墙钟时间(包括非运算的等待耗时)。

5、新生代介绍

> PSYoungGen      total 9216K, used 7265K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)

> eden space 8192K, 77% used [0x00000007bf600000,0x00000007bfc3b958,0x00000007bfe00000)

> from space 1024K, 86% used [0x00000007bfe00000,0x00000007bfedcb20,0x00000007bff00000)

> to   space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
  

表示新生代分为 eden区域、from区域,to区域,以及每个空间的大小,这里分别是 8M,1M,1M。

allocation1、allocation2、allocation3 各 2M,总共6M,存储在新生代eden区域,eden区域总共 8M,占比75%左右(垃圾回收之前)。

6、老年代介绍

表示老年代大小,和已使用的比例和容量

发生了MinorGC,但是发现allocation1、allocation2、allocation3不能都放入survivor区域,且没有被引用,都被回收掉了,所以allocation4,只能通过分配担保机制分配到老年代中,所以老年代占用4M,占比40%。

ParOldGen       total 10240K, used 4104K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  object space 10240K, 40% used [0x00000007bec00000,0x00000007bf002020,0x00000007bf600000)

7、元空间

表示元空间大小,和已使用的比例和容量

 Metaspace       used 3217K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 355K, capacity 388K, committed 512K, reserved 1048576K

GC日志分析工具:https://blog.csdn.net/Prepared/article/details/115368331

代码地址:https://github.com/prepared48/Java-learning.git
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Prepared/article/details/115368736