深刻理解JVM 垃圾收集器(下)G1收集器

  • 1.回顧CMS
    • 1.1堆內存結構
    • 1.2新生代GC
    • 1.3老年代GC
  • 2.G1收集器
    • 2.1G1實現概覽及使用場景
      • G1的推薦使用場景
    • 2.2GC
    • 2.2.1新生代GC
    • 2.2.2老年代GC
      • 老年代GC總結
    • 2.2.3 其餘
    • 2.4 最佳實踐
      • 2.4.1 JVM參數
        • 基本參數設置
        • 關鍵參數設置
  • 3.參考資料

1.回顧CMS

1.1堆內存結構

新生代分爲Eden區和兩個survivor區。老年代是一塊連續區域。html

只有FullGC時纔可能發生內存整理。java

1.2新生代GC

新生代淡綠色,老年代藍色。系統運行一段時間後CMS堆內存可能以下圖所示,對象分散在老年代各處。web

 

新生代存活對象從Eden區和survivor區複製到另外一個空閒的survivor區。任何minorGC年齡達到閾值的老對象被升級至老年代。算法

youngGC(minorGC)後,Eden區和一個survivor區被清空。api

新近升級至老年代的對象以深藍色表示。綠色對象是新生代仍存活的對象。多線程

1.3老年代GC

在初始標記和從新標記階段發生STW。當老年代剩餘空間達到閾值時(發生Concurrent Mode Failure),使用SerialOld替代CMS進行老年代GC。併發

(1)初始標記停頓時間很短,簡單的標記GCRoot引用的對象。(2)併發標記在標記存活對象時,應用繼續執行。(3)從新標記階段,標記併發階段遺漏的存活對象。oracle

未被標記的對象直接被回收。完成併發清掃後,許多老年代空間被釋放出來。同時內存整理仍沒有發生,老年代存在大量內存碎片。app

最終,CMS通過重置階段,等待下一次GC。ide

2.G1收集器

2.1G1實現概覽及使用場景

老式垃圾回收器(Serial,Parallel,CMS)統一將java堆分紅大小固定的三部分:新生代、老年代和永久代。全部內存對象最終都保存在這三個區域內。

G1收集器將java堆均分紅大小相同的區域(region,1M-32M,最多2000個,最大支持堆內存64G)。一個或多個不連續的區域共同組成eden、survivor或old區,但大小再也不固定,這爲內存應用提供了極大地彈性。G1垃圾收集過程與CMS相似。G1在堆內存中併發地對全部對象進行標記,決定對象的可達性。通過全局標記,G1瞭解哪些區域幾乎是空的,而後優先收集這些區域,這就是GarbageFirst的命名由來。G1將垃圾收集和內存整理活動專一於那些幾乎全是垃圾的區域,並創建停頓預測模型來決定每次GC時回收哪些區域,以知足用戶設定的停頓時間。

對於區域的回收經過複製算法實現。在完成標記清理後,G1將這幾個區域的存活對象複製到一個單獨區域中,實現內存整理和空間釋放。這一過程經過多線程並行進行來下降停頓時間,提升吞吐量。經過這樣的方式,G1在每次GC過程當中持續清理碎片,控制停頓時間知足用戶要求。這時過去虛擬機沒法作到的。CMS不清理內存碎片(除非經過虛擬機參數設置,在每次或屢次FullGC後進行整理),ParallelOld進行全堆整理,會致使較長的停頓時間。

G1不是實時垃圾收集器,它會盡可能讓停頓時間低於用戶設置的停頓時間目標但不能保證必定如此。G1根據歷史垃圾收集監測數據來 預測每一個區域的回收時間,而後根據用戶設定的目標停頓時間決定每次GC時能夠回收哪些區域。G1經過這種方式創建比較精確的區域回收時間預測模型。


G1的推薦使用場景

G1的設計初衷是爲用戶提供大內存、低GC停頓時間的應用解決方案。這意味着堆內存6G或更大,停頓時間穩定且少於0.5秒。

若是應用正在使用CMS或ParallelOld且面臨如下問題,推薦將應用遷移至G1

  • FullGC發生頻繁或總時間過長
  • 對象分配率或對象升級至老年代的比例波動較大
  • 較長的垃圾收集或內存整理停頓(大於0.5至1秒)

注意:若是應用沒有上述問題,不須要遷移虛擬機。G1並非最新JDK要求的虛擬機。

2.2GC

2.2.1新生代GC

存活對象移動到一個或多個survivor區域。若是對象達到晉升年齡,將被移動到老年代區域。

新生代GC總結:

  • 新生代垃圾回收(youngGC)須要STW,全部應用線程須要停頓。

  • youngGC多線程並行執行。

  • 存活對象複製到新的survivor區或老年代區。

2.2.2老年代GC

 

階段
描述
說明

初始標記

(Stop the world)

標記GC Roots直接引用的對象,新生代直接引用的老年代對象。

 

 

 

併發標記

標記堆中全部存活的對象。與用戶的應用程序併發執行。

在併發標記階段,若發現區域對象中的全部對象都是垃圾,那個這個區域會在從新標記階段被當即回收。

同時,併發標記過程當中,會計算每一個區域的對象活性(區域中存活對象的比例)。

從新標記

(Stop the world)

修正併發標記階段因用戶程序繼續運行而致使標記發生變更的那一部分標記記錄

若是發現徹底沒有活對象的region就會將其回收到空閒列表。

清除

(Stop the world)

清點和重置階段。

1)使用marking bitmap統計每一個region被標記爲活的對象有多少,統計每一個區域的對象活性(區域中存活對象的比例)。

2)重置Remembered Sets

 

複製

(Stop the world)

將存活的對象複製到未使用的region中。

G1選擇那些活躍度最低,回收速度最快的區域進行回收。

老年代GC總結

  • 併發標記階段
    • 區域活躍度信息的統計與應用線程併發進行
    • 活躍度信息決定了那個區域最早在清理階段被回收
    • 沒有CMS的清理階段
  • 再次標記階段
    • SATB算法比CMS使用的算法更快
    • 空區域在這個階段被回收
  • 複製/清理階段
    • 新生代和老年代同時被回收
    • 老年代根據活躍度肯定回收優先級

2.2.3 其餘

Remembered Set(可認爲是GC Roots的補充)

每個Region都有一個對應的Remembered Set,裏面記錄了全部來自外部的引用,這些引用將被認爲是GC roots的補充。

G1收集器中,Region之間的對象引用以及其餘收集器中的新生代和老年代之間的對象引用是使用Remembered Set來避免掃描全堆。
G1中每一個Region都有一個與之對應的Remembered Set,虛擬機發現程序對Reference類型數據進行寫操做時,會產生一個Write Barrier暫時中斷寫操做,檢查Reference引用的對象是否處於不一樣的Region之間(在分代中例子中就是檢查是否老年代中的對象引用了新生代的對象),若是是便經過CardTable把相關引用信息記錄到被引用對象所屬的Region的Remembered Set中。當內存回收時,在GC根節點的枚舉範圍加入Remembered Set便可保證不對全局堆掃描也不會有遺漏。

2.4 最佳實踐

2.4.1 JVM參數

基本參數設置

啓用G1 -XX:+UserG1GC
如下是使用G1收集器的javademo演示
java -Xmx50m -Xms50m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar c:\javademos\demo\jfc\Java2D\Java2demo.jar

關鍵參數設置

  • -XX:+UseG1GC - 啓用G1
  • -XX:MaxGCPauseMillis=200 - GC停頓的最長時間。這是一個軟目標,即虛擬機會盡最大可能知足這一時間,但某些狀況下仍可能超過。默認值爲200ms。
  • -XX:InitiatingHeapOccupancyPercent=45 - 堆內存使用率達到多少時啓動一次GC過程。GC過程涉及整個堆內存,不單指某個年齡代。設爲0時表示循環進行併發GC。默認值爲45,即堆內存使用45%後觸發一次GC。

3.參考資料

http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html  Getting Started with the G1 Garbage Collector

http://www.javashuo.com/article/p-kixkurda-ka.html Getting Started with the G1 Garbage Collector(中文)

https://www.jianshu.com/p/74dd0ffd4386?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation Java垃圾回收手冊(四):垃圾回收算法實現

http://blog.jobbole.com/109170/ 深刻理解Java G1垃圾收集器

http://hllvm.group.iteye.com/group/topic/44381 高級語言虛擬機論壇 [資料] [HotSpot VM] 請教G1算法的原理

相關文章
相關標籤/搜索