JVM常用基础参数-XX:+PrintGCDetails与GC参数详解

-XX:+PrintGCDetails 参数使用
YoungGC 日志的详解
Full GC 日志的详解
参数解读规律
-XX:+PrintGCDetails 参数使用
-XX:+PrintGCDetails 用于打印输出详细的GC收集日志的信息.

用于测试的代码如下 , 创建了一个50M的字节数组.

public class MyHelloGc {

public static void main(String[] args) throws InterruptedException {

    System.out.println("***************HELLO GC");

    byte[] bytesArr = new byte[50 * 1024 * 1024];
    
    //Thread.sleep(Integer.MAX_VALUE);
}

}

程序启动时,使用的JVM参数如下. 最大和最小的堆内存设置成了10m, 这样在运行上面的程序的时候, 一定会产生垃圾回收.
-Xms10m -Xmx10m -XX:+PrintGCDetails

程序运行后, 控制台打印如下
JVM常用基础参数-XX:+PrintGCDetails与GC参数详解

***************HELLO GC
[GC (Allocation Failure) [PSYoungGen: 1912K->496K(2560K)] 1912K->736K(9728K), 0.0017018 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 496K->480K(2560K)] 736K->728K(9728K), 0.0010814 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Allocation Failure) [PSYoungGen: 480K->0K(2560K)] [ParOldGen: 248K->659K(7168K)] 728K->659K(9728K), [Metaspace: 3031K->3031K(1056768K)], 0.0071285 secs] [Times: user=0.03 sys=0.00, real=0.01 secs]
[GC (Allocation Failure) [PSYoungGen: 0K->0K(2560K)] 659K->659K(9728K), 0.0008659 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(2560K)] [ParOldGen: 659K->643K(7168K)] 659K->643K(9728K), [Metaspace: 3031K->3031K(1056768K)], 0.0108306 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Heap
PSYoungGen total 2560K, used 101K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000)
eden space 2048K, 4% used [0x00000000ffd00000,0x00000000ffd195c0,0x00000000fff00000)
from space 512K, 0% used [0x00000000fff00000,0x00000000fff00000,0x00000000fff80000)
to space 512K, 0% used [0x00000000fff80000,0x00000000fff80000,0x0000000100000000)
ParOldGen total 7168K, used 643K [0x00000000ff600000, 0x00000000ffd00000, 0x00000000ffd00000)
object space 7168K, 8% used [0x00000000ff600000,0x00000000ff6a0e00,0x00000000ffd00000)
Metaspace used 3063K, capacity 4556K, committed 4864K, reserved 1056768K
class space used 323K, capacity 392K, committed 512K, reserved 1048576K
Exception in thread "main" java.lang.
at com.thc.jvmxx.MyHelloGc.main(MyHelloGc.java:17)
1
2
3

首先最明显的可以看到下面报出了 OutOfMemoryError: Java heap space 堆空间溢出的错误.
并且触发了GC 和 Full GC .

YoungGC 日志的详解
下图为GC日志的详解. 解释了每一个参数的含义.
JVM常用基础参数-XX:+PrintGCDetails与GC参数详解

以上面控制台打印的的GC打印日志举例解读.
[PSYoungGen: 1912K->496K(2560K)] 1912K->736K(9728K), 0.0017018 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

PSYoungGen 代表的是新生区的GC
1912K 代表的YoungGC前, 新生代占用1912k的内存
496K 代表YoungGC后, 新生代占用496K 的内存
2560K 代表 新生代总大小为 2560K
1912K 代表 YoungGC前, JVM堆内存的占用大小
736K 代表 YoungGC后, JVM堆内存的占用大小
9728K 代表JVM堆内存的总的大小. (大约为10m, 即项目启动时, 设置的10m的堆内存大小.)
0.0017018 secs 代表YoungGC 的耗时时间, 单位为秒
Times: user=0.00 sys=0.00, real=0.00 secs 分别为三个时间(了解) 分别为YoungGC 用户耗时时间, 系统耗时时间, 实际耗时时间. 单位为秒 .
Full GC 日志的详解
下2张图 为Full GC的详细解读

JVM常用基础参数-XX:+PrintGCDetails与GC参数详解

根据上面控制台打印的GC日志详细解读每一个参数的含义:
[Full GC (Allocation Failure) [PSYoungGen: 480K->0K(2560K)] [ParOldGen: 248K->659K(7168K)] 728K->659K(9728K), [Metaspace: 3031K->3031K(1056768K)], 0.0071285 secs] [Times: user=0.03 sys=0.00, real=0.01 secs]

Full GC 代表GC类型为Full GC 括号中的Allocation Failure ,代表分配空间失败.
PSYoungGen 代表新生代区
480K 代表GC前Young区 ,内存占用的大小
0K 代表GC后Young区 ,内存占用的大小. 把Young区的内存全部回收了
2560K 代表Young区 的总的大小.
ParOldGen 代表老年代区
248K 代表GC前Old区内存占用大小
659K 代表GC后Old区内存占用大小
7168K 代表Old区总的大小
728K 代表GC前堆内存占用大小
659K 代表GC后堆内存占用大小
9728K 代表堆的总大小
Metaspace 代表元空间. 图片中写的是PSPermGen 永久代为jdk7 的版本, jdk8 为元空间
3031K 代表GC前 元空间占用的大小
3031K 代表GC后 元空间占用的大小 (Full GC前后, 元空间的大小不变. )
1056768K 代表 元空间的总大小.
0.0071285 secs 代表 Full GC的消耗时间. 单位为秒
Times: user=0.03 sys=0.00, real=0.01 secs 分别为三个时间 分别为Full GC 用户耗时时间, 系统耗时时间, 实际耗时时间. 单位为秒 . 用于分析日志的性能
通过上面的分析可以看到, 在老年代GC前为248K , GC后Old区内存占用大小为659K . 代表 代码中 new byte[50 * 1024 * 1024];太大了, 无法被回收, 老年代都扛不住了, 所以报了Java heap space 堆空间溢出的错误.

参数解读规律
无论是Full GC 还是 Young GC ,解读日志都有如下的规律.
首先是该区域的名称, 接着是GC前的大小. -> 是GC后的大小. 接着是总的大小. 如果没有标明名称, 代表为堆的大小. 即堆的GC前 -> GC后大小, 总大小.

上一篇:请你谈谈频繁full gc怎么排查?


下一篇:启动flink集群后,无法进入localhost:8081页面