G1 GC日誌分析

使用UseG1GC這個選項顯示地要求JDK7或者JDK8對應的JVM採用G1 GC,據說JDK9開始默認GC會變更爲G1 GC(現在是ParallelGC),但一切皆有可能。

我們使用VM參數-XX:+PrintGCDetails-verbose:gc -Xloggc:gc.log -XX:+UseG1GC,日誌輸出如清單3-12所示。

代碼清單3-12 -XX:+UseG1GC運行輸出

Java HotSpot(TM) 64-BitServer VM (25.101-b13) for windows-amd64 JRE (1.8.0_101-b13), built on Jun 222016 01:21:29 by "Java_re" with MS VC++ 10.0 (VS2010)

Memory: 4k page, physical3922532k(1585004k free), swap 7843228k(5137568k free)

CommandLine flags:-XX:InitialHeapSize=62760512 -XX:MaxHeapSize=1004168192 -XX:+PrintGC-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers-XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation

Heap

 garbage-first heap   total 61440K, used 2048K[0x00000000c4200000, 0x00000000c43001e0, 0x0000000100000000)

 region size 1024K, 3 young (3072K), 0 survivors (0K)

 Metaspace      used 3953K, capacity 4716K, committed 4864K, reserved 1056768K

  class space   used 455K, capacity 468K, committed 512K, reserved 1048576K

 

G1 GC的日誌輸出和其他GC有所不同,它更加簡潔。這裏沒有進入一個評估階段,評估階段就是確認有多少對象需要被回收,通常是針對年輕代或者年輕代+老年代。從上面的輸出,我們可以看出一共有60M(61440/1024)的堆內存空間,其中使用了2M,Region是1M/個,有3個年輕代Region。元數據空間的使用情況也做了相應介紹,使用了3.8M,可用4.6M。

我們使用VM參數-XX:+PrintGCDetails-verbose:gc -Xloggc:gc.log -XX:+UseG1GC -XX:+PrintGCApplicationStoppedTime-XX:+PrintGCApplicationConcurrentTime運行應用程序,日誌輸出如清單3-13所示。

代碼清單3-13 -XX:+ PrintGCApplicationStoppedTime運行輸出

Java HotSpot(TM) 64-BitServer VM (25.101-b13) for windows-amd64 JRE (1.8.0_101-b13), built on Jun 222016 01:21:29 by "Java_re" with MS VC++ 10.0 (VS2010)

Memory: 4k page, physical3922532k(1449048k free), swap 7843228k(4974672k free)

CommandLine flags:-XX:InitialHeapSize=62760512 -XX:MaxHeapSize=1004168192 -XX:+PrintGC-XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers-XX:+UseCompressedOops -XX:+UseG1GC -XX:-UseLargePagesIndividualAllocation

1.159: Application time:0.8766273 seconds

1.160: Total time for which applicationthreads were stopped: 0.0001140 seconds, Stopping threads took: 0.0000351seconds

4.159: Application time:2.9998299 seconds

4.160: Total time for which applicationthreads were stopped: 0.0002126 seconds, Stopping threads took: 0.0000724seconds

4.418: Application time:0.2587571 seconds

4.419: Total time for which applicationthreads were stopped: 0.0001491 seconds, Stopping threads took: 0.0000381seconds

5.462: Application time:1.0433280 seconds

5.462: Total time for which applicationthreads were stopped: 0.0000664 seconds, Stopping threads took: 0.0000360seconds

Heap

 garbage-first heap   total 61440K, used 2048K[0x00000000c4200000, 0x00000000c43001e0, 0x0000000100000000)

 region size 1024K, 3 young (3072K), 0 survivors (0K)

 Metaspace      used 3953K, capacity 4716K, committed 4864K, reserved 1056768K

 class space    used 455K, capacity468K, committed 512K, reserved 1048576K

5.463:Application time: 0.0007787 seconds

 

我們來看一下這兩行輸出,

1.159: Application time: 0.8766273 seconds

1.160: Total time for which application threads were stopped:0.0001140 seconds, Stopping threads took: 0.0000351 seconds

這裏表示應用程序執行了0.87秒,GC線程造成的停頓時間大約爲0.0001140秒。由於程序運行過程中進行了多次回收,所以你看到這裏有多次時間打印。如果發現某個時間很長,那你要關注代碼和設計了,哪裏可能出現了實現或者設計弱點(不一定是缺陷),要根據實際情況進行優化,也許是代碼邏輯複雜造成的,也可能是代碼編寫時頻繁創建對象。

這裏應用程序會被暫停是由於G1GC針對年輕代(有時候是年輕代+老年代)有一個評估階段,這個評估階段實質上是在做數據拷貝,既然是拷貝,一定需要一個基準點[1],那麼爲了維護這個基準點,我們需要設置對應的應用程序暫停時間,這個時間段內就稱爲保護點(safepoint),這和Oracle的checkPoint很像。


歡迎關注麥克叔叔每晚十點說,感興趣的朋友可以關注公衆號,讓我們一起學習與交流。

[1] 即大家都認爲這個時間點的數據是完好無缺的,永遠不要認爲軟件應該無縫隙保證數據完整性,這個和CAP原理相違背,一定是通過其他方式來確保數據的原子性、完整性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章