基於JDK1.7Update14之後的HotSpot虛擬機垃圾收集器

HotSpot虛擬機垃圾收集器概覽圖,收集器工作的內存區域以及收集器之間的配合使用情況。如下圖所示:
這裏寫圖片描述

1.Serial收集器

Serial是最基本,歷史最悠久的收集器,在Jdk1.3以前是虛擬機唯一的新新生代收集器。
它的特點:

 1. 單線程收集器,它只會使用一個CUP或者說一條收集線程來完成垃圾收集;
 2. Stop The World,當進行垃圾收集時必須暫停所有的工作線程,直到它收集結束。
 3. 使用“複製”算法,

現狀及優勢


 1. 現在目前國止,它依然是虛擬機運行在Client模式下的默認新生代收集器
 2. 相比其他單線程收集器簡單而高效,針對單CPU環境來說,沒有線程交互開銷。
 3. 對於用戶桌面應用來說,新生代使用的內存不會太大,停頓時間完全可以控制在幾十毫秒以內,完全能勝任。

2.ParNew收集器

ParNew是Serial收集器的多線程版本, 除了多線程的區別外,其他作爲包括Serial收集器可用的所有控制參數、收集算法、Stop The World、回收策略等都與Serial完全一樣。
它的特點:


 1. 是Serial收集器的多線程版本,
 2. 也是新生代收集器,
 3. 使用“複製”算法
 4. 它是許多運行在Server模式下的虛擬機中首選的新生代收集器,
 5. ParNew是能與CMS收集器配合工作的其中一個,另一個就是Serial收集器。
 6. ParNew在單CPU環境並不比Serial收集器更好,反而可能由於線程交互而使性能不如Serial
 7. ParNew默認開啓的線程數與CPU數量相同。
 8. -XX:+UseParNewGC 添加該虛擬機參數後,虛擬機強制使用ParNew收集器。
 9. -XX:ParallelGCThreads參數來限制垃圾收集器的線程數。

3.Parallel Scavenge收集器

它是一個新生代收集器,它使用複製算法,且是並行的多線程收集器。Parallel Scavenge收集器的目的是達到一個可控制的吞吐量(Throughput)。所謂吞吐量就是CPU用於運行用戶代碼的時間與CPU總消耗的時間的比值,即吞吐量=運行用戶代碼時間/(運行用戶代碼時間+垃圾收集時間)。虛擬機總共運行了100分鐘,用於垃圾收集花了1分鐘,那麼吞吐量就是99%。
它的特點:


 1. 新生代收集器,
 2. 使用“複製”算法;
 3. 並行的多線程收集器;
 4. 關注點在於,可控制的吞吐量
 5. 提供兩個參數實現吞吐量的控制,
     -XX:MaxGCPauseMillis 控制最大垃圾收集停頓時間,允許設置大於0的毫秒數
     -XX:GCTimeRatio 直接設置吞吐量大小。取值爲大於0小於100的整數
     -XX:+UseAdaptiveSizePolicy 讓虛擬機根據系統情況動態調整新生代大小,eden與Survivor比例、晉升老年代對象年齡等參數;若設置了此參數,用戶只需要設置最大堆大小(-Xmx)和MaxGCPauseMillisXX:GCTimeRatio

4.Serial Old收集器

Serial Old 是Serial收集器的老年代版本,它同樣是單線程收集器,使用“標記——整理”算法。它主要意義在於給Client模式 下的虛擬機使用。若在Server模式 下,它主要還有兩大用途:一種是在JDK1.5以及之前的版本 與Parallel Scavenge收集器搭配使用;另一種是作爲CMS收集器的後備預案。
它的特點:


 1. 老年代收集器,Serial的老年代版本;
 2. 單線程收集器;
 3. 使用“標記——整理”算法;
 4. 可與Parallel Scavenge收集器搭配使用;
 5. Stop The World

5.Parallel Old收集器

Parallel Old是Parallel Scavenge收集器的老年代版本,使用多線程“標記——整理”算法,在JDK1.6中開始提供使用。Parallel Old出現之前,Parallel Scavenge只能與Serial Old配合使用,Serial Old單線程的特性導致老年代垃圾收集瓶頸所以Parallel Scavenge略顯尷尬。在Parallel Old收集器出現以後,Parallel Scavenge的“吞吐量優先”收集器才變得名副其實。在注重吞吐量以及CPU資源敏感的場合,都可以優先考慮Parallel Scavenge +Parallel Old收集器組合。
它的特性:


 1. 老年代收集器;
 2. 多線程;
 3. 使用“標記——整理”算法;
 4. Stop The World;

6.CMS收集器

CMS(Concurrent Mark Sweep)收集器是一種以獲得最短回收停頓時間爲目標的收集器。對於重視服務的響應速度,希望系統停頓時間最短,以給用記帶來較好的體驗的應用(互聯網或B/S系統服務端),CMS非常符合這類應用需求。它基於“標記——清除”算法。收集過程分爲4步:


 1. 初始標記(Stop The Wold),標記GC Root能直接關聯到的對象,速度快
 2. 併發標記(與用戶線程並行執行),GC Roots Tracing,標記與GC Root關聯對象引用的對象;
 3. 重新標記,(Stop The Wold),修正併發標記期間因用戶程序繼續動作而導致標記變動的部分對象的標記記錄;
 4. 併發清除(與用戶線程並行),運行時間稍長,但由於與用戶線程併發,所以影響不大。

優點:


 1. 併發收集;
 2. 低停頓。

缺點:

 1. CMS收集器對CPU資源非常敏感,CMS默認啓動的回收線程數是(CPU數量+3)/4。
 2. CMS無法處理浮動垃圾,浮動垃圾就是收集過程中由於用戶線程執行新產生的垃圾
 3. 會產生大量的空間碎片;也提供了參數設置,執行多少次垃圾收集後進行一次碎片合併整理]
     -XX:UseCMSCompactAtFullCollection 默認開啓,在fullGC時開啓內存碎片合併整理
     -XX:CMSFullGCsBeforeCompaction 設置多少次fullGc後執行一次碎片合併整理。

7.G1收集器

G1收集器是當今收集器技術發展的最前沿成果之一,它是一款面向服務端應用的垃圾收集器。HotSpot開發團隊賦予化的使命是未來可以替換掉JDK1.5中發佈的CMS收集器。與其他GC收集器相比,G1此具備如下特點:


 1. 並行與併發,G1能充分複用CPU、多核環境下的硬件優勢,使用多個CPU來縮短Stop-The_World停頓的時間,部分其他收集器原需要停頓Java線程執行的GC動作,G1收集器仍然可以通過併發的方式讓Java程序繼續執行。

 2. 分代收集,當G1無需與其他收集器配合就能獨立管理整個GC堆。但它採取的方式與一般的收集器有所不同。

 3. 空間整合,與CMS的“標記——清理”算法不同,G1從整體來看是基於“標記——整理”算法的收集器,從局部上來看是基於“複製”算法實現的,但兩種算法都意味着G1動作期間不會產生內存空間碎片。

 4. 可預測的停頓,這是G1相對於CMS的另一大優勢,降低停頓時間是G1和CMS其同的關注點,但G1除了追求低停頓外,還能建立可預測的停頓時間模型,能讓使用者明確指定在一個長度爲M毫秒的時間片段內,消耗在垃圾收集上的時間不得超過N毫秒,這幾乎已經是實時Java的垃圾收集器的特徵了。

它的原理:

  1. 它將整個java堆劃分 爲多個大小相等的獨立區域(Region),雖然還保留有新生代和老年低的概念,但新生代和老年代不再是物理隔離的,它們都是一部分Region(不需要連續)的集合。
  2. G1收集器之所以能建立可預測的停頓時間模型,是因爲它可以有計劃地避免在整個Java堆中進行全區域的垃圾收集。G1跟蹤各個Region裏面的垃圾信積的價值大小(回收所獲得的空間大小 以及回收所需時間的經驗值),在後臺維護一個優先列表, 每次根據允許的收集時間,優先回收價值了大的Region(這也是Garbage_first名稱的由來)。這種使用Region劃分內存空間以及有優先級的區域回收方式,保證了G1收集器在有限的時間內可以獲得儘可能 高的收集效率。
  3. 每個Region維護一個Remembered Set 來維護區域中引用對象的信息,這樣避免GC是的全堆掃描。

它的執行步驟:


 1. 初始標記,僅僅是標記一下GC Roots能直接關聯到的對象,運行很快,會Stop The World.
 2. 併發標記,從GC Root開始對堆中的對象進行可達性分析,找出存活對象,耗時較長,但與用戶線程同時運行,
 3. 最終標記,則是爲了修正在併發標記期間因用戶程序繼續運作而導致標記產生變動的那一部分標記記錄,停頓用戶線程。
 4. 篩選回收,首先對各個Region的回收價值和成本進行排序,根據用戶所期望的GC停頓時間來制定回收計劃。這階段會停頓用戶線程,該階段其實也可能用戶線程併發執行,但因爲只回收一部分Region,時間是用戶控制的,所以停頓用戶線程提高收集效率。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章