-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
程序運行后, 控制台打印如下
***************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日志的詳解. 解釋了每一個參數的含義.
以上面控制台打印的的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的詳細解讀
根據上面控制台打印的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后大小, 總大小.