1.G1
概述
-
為什么有了前面幾個強大的垃圾收集器,還需要
Garbage First(G1) GC
?
隨着應用程序所應對的業務越來越龐大、復雜,前面幾款垃圾收集器已經不能滿足實際的需要,所以出現了G1
。 -
G1
是在延遲可控的情況下,獲得盡可能高的吞吐量,所以才擔當起“全功能收集器”的重任與期望。(全功能收集器的意思是它既負責新生代的垃圾回收又負責老年代的垃圾回收) -
G1
收集器將堆內存划分為很多不想關的區域(Region)
(物理上可以是不連續的空間),使用不同的Region
來表示Eden
,S0
區,S1
區,老年代等等。 -
G1
有計划的避免在整個Java
堆中進行全區域的垃圾收集,G1
會跟蹤各個Region
里面的垃圾堆積的價值大小(回收所獲得的空間大小以及回收所需要的時間經驗值),在后台維護一個優先列表,每次根據允許的收集時間,優先回收價值最大的Region
。 -
G1
在JDK7
中正式啟用,但不是默認的垃圾收集器,在JDK9
中成為了默認的垃圾收集器,取代了CMS
以及Parallel + Parallel Old
組合。在JDK7
以及JDK8
中,可以使用-XX:+UseG1GC
來啟用。 -
G1
將堆空間划分為若干個區域(Region
),各個region
可以是Eden
區,Survivor
區以及Old
區等。
2.G1
的優勢與缺點
優勢:
- 並行與並發 - 多個垃圾收集線程同時工作(並行),垃圾收集線程與用戶線程交替執行(並發)。
- 分代收集 -
G1
將堆空間划分為若干個區域(Region
),這些區域中包含了邏輯上的年輕代和老年代。它不要求年輕代,老年代是連續的。同時,G1
同時兼顧年輕代和老年代的垃圾回收,其他的垃圾收集器,要么工作在年輕代,要么工作在老年代。 - 空間整合(內存碎片整理) -
G1
內存回收使用Region
作為基本單位,Region
之間使用的是復制算法,能夠對內存空間進行整理。 - 可預測的停頓時間模型 - 可以讓用戶明確指定在一個長度為
M
毫秒的時間片段內,消耗在垃圾收集上的時間不得超過N
毫秒。
缺點:
相比於CMS
,G1
還不具備全方位、壓倒性優勢。比如,G1
為了垃圾收集產生的內存占用
以及程序運行時的額外執行負載
都比CMS
要高。
3.G1
參數設置
-XX:G1HeapRegionSize
設置每個region
的大小,值只能是2
的n
次方(1,2,4,8,16,32
),范圍是1MB
到32MB
。-XX:MaxGCPauseMillis
設置期望達到(JVM
會盡力實現,但不保證)的最大GC
停頓時間,默認是200ms
。 這個參數如果設置的過小,會導致一次回收的region
個數減少,回收的垃圾對象減少(因為設置的垃圾線程工作的時間減少了),如果產生垃圾的速度很快,可能會導致Full GC
。-XX:ParallelGCThread
設置STW
的時候並行的垃圾線程數量。-XX:ConcGCThreads
設置用戶線程與垃圾收集線程並發的時候,垃圾收集線程的線程數量
通常使用G1
收集器,不需要那么多的參數配置。只需要進行下圖所示的3
步。其他的參數,G1
會自動調節或使用默認的參數。