-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
程序运行后, 控制台打印如下
***************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)
首先最明显的可以看到下面报出了 OutOfMemoryError: Java heap space 堆空间溢出的错误.
并且触发了GC 和 Full GC .
下图为GC日志的详解. 解释了每一个参数的含义.
以上面控制台打印的的GC打印日志举例解读.
[PSYoungGen: 1912K->496K(2560K)] 1912K->736K(9728K), 0.0017018 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
下2张图 为Full 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]
通过上面的分析可以看到, 在老年代GC前为248K , GC后Old区内存占用大小为659K . 代表 代码中 new byte[50 * 1024 * 1024];
太大了, 无法被回收, 老年代都扛不住了, 所以报了Java heap space 堆空间溢出的错误.
无论是Full GC 还是 Young GC ,解读日志都有如下的规律.
首先是该区域的名称, 接着是GC前的大小. -> 是GC后的大小. 接着是总的大小. 如果没有标明名称, 代表为堆的大小. 即堆的GC前 -> GC后大小, 总大小.