3.1、JVM學習——GC日誌含義與配置

前言

GC 日誌可以提供虛擬機各分代垃圾回收的情況,需要注意的是,不同的垃圾回收器在GC 日誌中名字並不相同。

JDK 版本

本文使用 JDK 1.8 x64 進行相關測試

測試代碼

從實踐來說,可以通過限制虛擬機內存大小,然後不斷創建對象來觸發 GC,也可以直接調用 System.gc(),本文采用了後者——更簡單,直觀。
當然,作爲測試,我們還是增加了一些JVM 的配置參數,用於日誌能夠展示在控制檯上

-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3145728

public class GcTest {
		//-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3145728
		private static final int _1MB = 1024 * 1024;
		private static final int _4MB = 4*1024 * 1024;

		/**
		 * 小對象先保存到 新生代 Eden
		 */
	    public static void testThreshold(){
	        byte[] allocation;
	        allocation = new byte[1 * _1MB];
	    }
	    
	    /**
	     * 大對象直接進入老年代
	     * -XX:PretenureSizeThreshold=3145728
	     */
	    public static void testPretenureSizeThreshold(){
	        byte[] allocation;
	        allocation = new byte[1 * _4MB];
	    }

	    public static void main(String[] args) {
	    	//觸發老年代GC
	    	for(int j=0;j<3;j++) {
	    		testPretenureSizeThreshold();
	    	}
	    	
	    	//觸發新生代GC
	    	for(int i=0;i<10;i++) {
	    		GcTest.testThreshold();
	    	}
	    	
	    	//手動觸發GC
			System.gc();	
	    }
}

控制檯內容

控制檯內容包含了兩個部分,第一個部分是 GC 信息,第二個部分是 Heap 信息
其中 GC 信息就是本文要介紹的GC 日誌。
Heap 信息屬於PrintGCDetails 的附加信息。

[GC (System.gc()) [PSYoungGen: 1740K->729K(9216K)] 1740K->737K(19456K), 0.0016883 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [PSYoungGen: 729K->0K(9216K)] [ParOldGen: 8K->596K(10240K)] 737K->596K(19456K), [Metaspace: 2677K->2677K(1056768K)], 0.0053865 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 
Heap
 PSYoungGen      total 9216K, used 82K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 8192K, 1% used [0x00000007bf600000,0x00000007bf614920,0x00000007bfe00000)
  from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
  to   space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
 ParOldGen       total 10240K, used 596K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  object space 10240K, 5% used [0x00000007bec00000,0x00000007bec950e8,0x00000007bf600000)
 Metaspace       used 2684K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K

內容解析-GC 信息

[GC (System.gc()) [PSYoungGen: 1740K->729K(9216K)] 1740K->737K(19456K), 0.0016883 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [PSYoungGen: 729K->0K(9216K)] [ParOldGen: 8K->596K(10240K)] 737K->596K(19456K), [Metaspace: 2677K->2677K(1056768K)], 0.0053865 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 

GC 日誌以是否Stop The World 分爲兩類

GC 日誌可以分爲兩種,一種是 [GC開頭,一種是 [Full GC開頭,二者的區別在於,[Full GC表明該垃圾回收過程發生了 Stop The World,需要強調的是,不要將GC 日誌中 Full GC 關鍵字和 老年代的垃圾回收 Full GC 混淆,在GC 日誌中 年輕代和老年代的日誌是在一起的。

如果垃圾回收是由 Java 代碼 System.gc()來觸發的,則GC 日誌中會增加一個(System.gc()),如本文的 [GC (System.gc()) 和 [Full GC (System.gc())
如果垃圾回收是由於內存空間不夠,則會顯示分配失敗 [GC (Allocation Failure)
此外還會有其他類型的情況

[GC````和``[Full GC中間部分的含義:PsYoungGen 是年輕代的垃圾回收信息
ParOldGen是老年代的垃圾回收信息
Metaspace是元空間的垃圾回收信息
最後一部分 Times 表示垃圾回收期間各部分時間段佔用的事件比重

比如 [PSYoungGen: 729K->0K(9216K)]
表示:新生代使用的是 ParallelGC 這種垃圾回收器,新生代總大小爲 9216K,垃圾回收前後的內存佔用大小爲 729K->0K ,即所佔用的 729K 空間全部被回收了

不同垃圾回收器日誌關鍵字不同

GC 日誌使用不同的關鍵字來區分不同的垃圾回收期,你應該瞭解到虛擬機垃圾回收器有多種不同的搭配方式。本文在下面內容中通過不同的VM 配置對不同情況下的GC日誌關鍵字進行歸納總結。

新生代、老年代垃圾回收器的搭配連線圖(CMS 是可以和 Serial Old 同時使用的)

在這裏插入圖片描述

內容解析-Heap 信息

Heap
 PSYoungGen      total 9216K, used 82K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 8192K, 1% used [0x00000007bf600000,0x00000007bf614920,0x00000007bfe00000)
  from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
  to   space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
 ParOldGen       total 10240K, used 596K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  object space 10240K, 5% used [0x00000007bec00000,0x00000007bec950e8,0x00000007bf600000)
 Metaspace       used 2684K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K

Heap 信息還是很明顯的,PSYoungGen 表示年輕代垃圾回收器爲 Parallel Scavenge,此外還有年輕代的 eden 、from、to 的信息;ParOldGen 表示老年代垃圾回收器爲 Parallel Old,Metaspace 表示元數據信息,
total 表示總大小,used 表示已用

通過 Heap 信息,也可以分辨出來當前所用的是何種垃圾回收器

指定垃圾回收器與GC 關鍵字

通過參數指定垃圾回收器

參數 描述
-XX:+UseSerialGC def new generation (Serial)
-XX:+UseParNewGC par new generation
-XX:+UseParallelGC PSYoungGen
-XX:+UseParallelOldGC PSYoungGen
-XX:+UseConcMarkSweepGC (CMS) par new generation

其他參數延伸

參數 描述
SurvivorRatio
PretenureSizeThreshold
MaxTenuringThreshold
UseAdaptiveSizePolicy
HandlePromotionFailure
ParallelGCThreads
GCTimeRatio
MaxGCPauseMills
CMSInitiatingOccupancyFraction
UseCMSCompactAtFullCollection
CMSFullGCsBeforeCompaction

垃圾回收器關鍵字規律總結

配置 年輕代 老年代 元數據
-XX:+UseSerialGC def new generation tenured generation Metaspace
-XX:+UseParNewGC par new generation tenured generation Metaspace
-XX:+UseParallelGC PSYoungGen ParOldGen Metaspace
-XX:+UseParallelOldGC PSYoungGen ParOldGen Metaspace

GC 詳情展示

-XX:+UseSerialGC

垃圾回收器: Serial+ SerialOld
GC 日誌

[GC (Allocation Failure) [Tenured: 8192K->596K(10240K), 0.0034819 secs] 9932K->596K(19456K), [Metaspace: 2678K->2678K(1056768K)], 0.0035603 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [DefNew: 7331K->0K(9216K), 0.0003829 secs] 12024K->4692K(19456K), 0.0004152 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [Tenured: 4692K->596K(10240K), 0.0031400 secs] 7928K->596K(19456K), [Metaspace: 2678K->2678K(1056768K)], 0.0031873 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

堆信息

 Heap
 def new generation   total 9216K, used 82K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  eden space 8192K,   1% used [0x00000007bec00000, 0x00000007bec14920, 0x00000007bf400000)
  from space 1024K,   0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000)
  to   space 1024K,   0% used [0x00000007bf500000, 0x00000007bf500000, 0x00000007bf600000)
 tenured generation   total 10240K, used 596K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
   the space 10240K,   5% used [0x00000007bf600000, 0x00000007bf6950e8, 0x00000007bf695200, 0x00000007c0000000)
 Metaspace       used 2684K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K

-XX:+UseParNewGC

垃圾回收器: PawNew+64位時 SerialOld
GC 日誌

Java HotSpot(TM) 64-Bit Server VM warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release
[GC (Allocation Failure) [Tenured: 8192K->596K(10240K), 0.0045567 secs] 9932K->596K(19456K), [Metaspace: 2678K->2678K(1056768K)], 0.0046114 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[GC (Allocation Failure) [ParNew: 7331K->0K(9216K), 0.0005674 secs] 12024K->4692K(19456K), 0.0006037 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [Tenured: 4692K->596K(10240K), 0.0024158 secs] 7928K->596K(19456K), [Metaspace: 2678K->2678K(1056768K)], 0.0024644 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 

堆信息

Heap
 par new generation   total 9216K, used 82K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  eden space 8192K,   1% used [0x00000007bec00000, 0x00000007bec14920, 0x00000007bf400000)
  from space 1024K,   0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000)
  to   space 1024K,   0% used [0x00000007bf500000, 0x00000007bf500000, 0x00000007bf600000)
 tenured generation   total 10240K, used 596K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
   the space 10240K,   5% used [0x00000007bf600000, 0x00000007bf6950e8, 0x00000007bf695200, 0x00000007c0000000)
 Metaspace       used 2684K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K

-XX:+UseParallelGC

垃圾回收器: Parallel Scavenge+Parallel Old
GC 日誌

[GC (Allocation Failure) [PSYoungGen: 7884K->745K(9216K)] 16076K->8946K(19456K), 0.0018850 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 8077K->681K(9216K)] 16277K->8882K(19456K), 0.0015061 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (System.gc()) [PSYoungGen: 2025K->665K(9216K)] 10225K->8874K(19456K), 0.0010182 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
[Full GC (System.gc()) [PSYoungGen: 665K->0K(9216K)] [ParOldGen: 8208K->594K(10240K)] 8874K->594K(19456K), [Metaspace: 2679K->2679K(1056768K)], 0.0052985 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 

堆信息

Heap
 PSYoungGen      total 9216K, used 82K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 8192K, 1% used [0x00000007bf600000,0x00000007bf614920,0x00000007bfe00000)
  from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
  to   space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
 ParOldGen       total 10240K, used 596K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  object space 10240K, 5% used [0x00000007bec00000,0x00000007bec950e8,0x00000007bf600000)
 Metaspace       used 2683K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K

-XX:+UseParallelOldGC

垃圾回收器: Parallel Scavenge+Parallel Old
GC 日誌

[GC (Allocation Failure) [PSYoungGen: 7884K->729K(9216K)] 16076K->8930K(19456K), 0.0018887 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 8061K->713K(9216K)] 16261K->8914K(19456K), 0.0014337 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[GC (System.gc()) [PSYoungGen: 2057K->633K(9216K)] 10257K->8842K(19456K), 0.0010012 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [PSYoungGen: 633K->0K(9216K)] [ParOldGen: 8208K->594K(10240K)] 8842K->594K(19456K), [Metaspace: 2679K->2679K(1056768K)], 0.0047913 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 

堆信息

Heap
 PSYoungGen      total 9216K, used 82K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 8192K, 1% used [0x00000007bf600000,0x00000007bf614920,0x00000007bfe00000)
  from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
  to   space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
 ParOldGen       total 10240K, used 596K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  object space 10240K, 5% used [0x00000007bec00000,0x00000007bec950e8,0x00000007bf600000)
 Metaspace       used 2684K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K

-XX:+UseConcMarkSweepGC

垃圾回收器: ParNew+CMS
GC 日誌

[GC (Allocation Failure) [CMS: 8192K->600K(10240K), 0.0039740 secs] 9932K->600K(19456K), [Metaspace: 2677K->2677K(1056768K)], 0.0040636 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [ParNew: 7331K->0K(9216K), 0.0005220 secs] 12028K->4696K(19456K), 0.0005620 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [CMS: 4696K->599K(10240K), 0.0022873 secs] 7932K->599K(19456K), [Metaspace: 2678K->2678K(1056768K)], 0.0023498 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

堆信息

Heap
 par new generation   total 9216K, used 82K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
  eden space 8192K,   1% used [0x00000007bec00000, 0x00000007bec14920, 0x00000007bf400000)
  from space 1024K,   0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000)
  to   space 1024K,   0% used [0x00000007bf500000, 0x00000007bf500000, 0x00000007bf600000)
 concurrent mark-sweep generation total 10240K, used 600K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
 Metaspace       used 2683K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 288K, capacity 386K, committed 512K, reserved 1048576K
發佈了459 篇原創文章 · 獲贊 229 · 訪問量 187萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章