深入理解G1垃圾收集器
G1(Garbage First)垃圾收集器是當今垃圾回收技術最前沿的成果之一。早在JDK7就已加入JVM的收集器大家庭中,成為HotSpot重點發展的垃圾回收技術,JDK9 默認就是使用的G1垃圾收集器。
不同于其他的分代回收算法,G1最大的特點是引入分區的思路,弱化了分代的概念,合理利用垃圾收集各個周期的資源,解決了其他收集器甚至CMS的眾多缺陷。每塊區域既有可能屬于O區、也有可能是Y區,且每類區域空間可以是不連續的(對比CMS的O區和Y區都必須是連續的)。
G1有三個明顯特點:1、壓縮空間強,避免碎片\color{red}{壓縮空間強,避免碎片}壓縮空間強,避免碎片 2、空間使用更靈活 3、GC停頓周期更可控,避免雪崩\color{red}{GC停頓周期更可控, 避免雪崩}GC停頓周期更可控,避免雪崩
G1其實是Garbage First的意思,垃圾優先? 不是,是優先處理那些垃圾多的內存塊的意思。
一般的垃圾回收器把內存分成三類: Eden(E), Suvivor(S)和Old(O)。
G1雖然也把內存分成了這三大類,但是在G1里面這三大類不是涇渭分明的三大塊內存,G1把內存劃分成很多小塊, 每個小塊會被標記為E/S/O中的一個,可以前面一個是Eden后面一個就變成Survivor了。
這么做給G1帶來了很大的好處,由于把三塊內存變成了幾百塊內存,內存塊的粒度變小了,從而可以垃圾回收工作更徹底的并行化。
G1的并行收集做得特別好,我們第一次聽到并行收集應該是CMS(Concurrent Mark & Sweep)垃圾回收算法, 但是CMS的并行收集也只是在收集老年代能夠起效,而在回收年輕代的時候CMS是要暫停整個應用的(Stop-the-world)。而G1整個收集全程幾乎都是并行的。
它回收的大致過程是這樣的:
G1的另一個顯著特點他能夠讓用戶設置應用的暫停時間,為什么G1能做到這一點呢?
也許你已經注意到了,G1回收的第4步,它是“選擇一些內存塊”,而不是整代內存來回收,這是G1跟其它GC非常不同的一點,其它GC每次回收都會回收整個Generation的內存(Eden, Old), 而回收內存所需的時間就取決于內存的大小,以及實際垃圾的多少,所以垃圾回收時間是不可控的;而G1每次并不會回收整代內存,到底回收多少內存就看用戶配置的暫停時間\color{red}{到底回收多少內存就看用戶配置的暫停時間}到底回收多少內存就看用戶配置的暫停時間,配置的時間短就少回收點,配置的時間長就多回收點 ,伸縮自如。
由于內存被分成了很多小塊,又帶來了另外好處,由于內存塊比較小,進行內存壓縮整理的代價都比較小,相比其它GC算法,可以有效的規避內存碎片的問題。
記憶集Remembered Set:
G1相關概念非常多,有一個重點就是Remembered Set,用于記錄和維護region之間對象的引用關系。為什么需要這么做呢?試想,新生代GC是復制算法,也就是說,類似對象 從Eden或者Survivor到to區域的“移動”,其實是“復制”,本質上是一個新的對象。在這個過程中,需要必須保證老年代到新生代的跨區引用仍然有效。比如card table是remembered set的一種實現。下面的示意圖說明了相關設 計。
G1 的缺點:
G1 需要記憶集 (具體來說是卡表,Remembered Set)來記錄新生代和老年代之間的引用關系,這種數據結構在 G1 中需要占用大量的內存,可能達到整個堆內存容量的 20% 甚至更多。而且 G1 中維護記憶集的成本較高,帶來了更高的執行負載,影響效率。
G1對比CMS的區別在:
目前CMS還是默認首選的GC策略、可能在以下場景下G1更適合:
G1 的 JVM調優
1、region太小不合適,會令你在分配大對象時更難找到連續空間
-XX:G1HeapRegionSize=<N, 例如16>M
2、老年代回收,則是依靠Mixed GC,指定觸發閾值,并且設定最多被包含在一次Mixed GC中的region比例
–XX:G1MixedGCLiveThresholdPercent –XX:G1OldCSetRegionThresholdPercent
3、在垃圾收集過程中,G1會把新創建的字符串對象放入隊列中,然后在Young GC之后,并發地(不會STW)將內部數據 (char數組,JDK 9以后是byte數組)一致的字符串進行排重,也就是將其引用同一個數組。你可以使用下面參數激活
-XX:+UseStringDeduplication
4、G1只有在發生Full GC時才進行類型卸載,但這顯然不是我們想要的。你可以加上下面的參數,在并發標記階段結束后,JVM即進行類型卸載
-XX:+ClassUnloadingWithConcurrentMark
5、建議開啟選項下面的選項進行并行引用處理
-XX:+ParallelRefProcEnabled
總結
G1是一款壓縮型的收集器.G1通過有效的壓縮完全避免了對細微空閑內存空間的分配,不用依賴于regions,這不僅大大簡化了收集器,而且還消除了潛在的內存碎片問題。除壓縮以外,G1的垃圾收集停頓也比CMS容易估計,也允許用戶自定義所希望的停頓參數(pause targets)
總結
以上是生活随笔為你收集整理的深入理解G1垃圾收集器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS 全站漂浮
- 下一篇: Tomcat| 设置https端口时,8