JVM——垃圾收集器

概念補充


  並行(Parallel):指多條垃圾收集線程並行工做,但此時用戶線程仍然處於等待狀態。
  併發(Concurrent):指用戶線程與垃圾收集線程同時執行(但不必定是並行的,可能會交替執行),用戶程序在繼續運行,而垃圾收集程序運行於另外一個CPU上。算法

  全部的GC算法都將堆劃分紅了老年代和新生代。多線程

  全部的GC算法在清理新生代對象時,都使用了「時空停頓(stop-the-world)」方式的垃圾收集方式,一般這是一個能較快完成的操做。併發

Serial收集器:


  Serial/Serial Old收集器是最基本、發展歷史最悠久的收集器,屬於單線程的收集器,採用複製算法進行垃圾收集,它在進行垃圾收集時,必須暫停其餘全部的工做線程,直到它收集結束。
  它是虛擬機運行在Client模式下的默認新生代收集器。
  它也有着優於其餘收集器的地方:簡單而高效。
  對於限定單個CPU的環境來講,Serial收集器因爲沒有線程交互的開銷,專心作垃圾收集天然能夠得到最高的單線程收集效率。因此,Serial收集器對於運行在Client模式下的虛擬機來講是一個很好的選擇。佈局

ParNew收集器:


  並行,ParNew收集器其實就是Serial收集器的多線程版本,除了使用多線程進行垃圾收集以外,其他行爲與Serial收集器徹底同樣。
  雖然它與Serial相比,除了多線程收集以外沒有其餘不一樣之處,但它倒是許多運行在Server模式下的虛擬機中首選的新生代收集器,除了Serial收集器外,目前只有它能與CMS收集器配合工做。
  在JDK1.5中使用CMS來收集老年代的時候,新生代只能選用ParNew或者Serial收集器中的一個。
  ParNew收集器在單CPU環境中絕對不會有比Serial收集器更好的效果。不過,隨着可使用的CPU的數量的增長,它對於GC時系統資源的有效利用仍是頗有好處的。spa

Parallel Scavenge收集器:


  並行,Parallel Scavenge收集器是一個新生代收集器,它也是使用複製算法的收集器。
  其特色是它的關注點與其餘收集器不一樣,CMS等收集器的關注點是儘量地縮短垃圾收集時用戶線程的停頓時間,其目標則是達到一個可控制的吞吐量(Throughput)。
  其提供兩個參數用於精確控制吞吐量,分別是控制最大垃圾收集停頓時間:-XX:MaxGCPauseMillis參數以及直接設置吞吐量大小的-XX:GCTimeRatio參數。
  因爲與吞吐量關係密切,其也常常稱爲「吞吐量優先」收集器。線程

Serial Old收集器:


  串行其是Serial收集器的老年代版本,一樣是單線程收集器,使用「標記-整理」算法。對象

Parallel Old收集器:


  並行,其是Parallel Scavenge收集器的老年代版本,使用多線程和「標記-整理」算法。內存

CMS收集器:


  Sun也稱其爲Concurrent Low Pause Collector(併發低停頓收集器)其是一種以獲取最短回收停頓時間爲目標的收集器。其是基於「標記-清除」算法實現。ci

  它的運做過程相對於前面幾種收集器來講更復雜一些,整個過程分爲4個步驟:資源

  • 初始標記:初始標記僅標記一下GC Roots能直接關聯到的對象,速度很快;
  • 併發標記:初始標記和從新標記任然須要「stop the world」,併發標記過程就是進行GC Roots Tracing的過程;
  • 從新標記:修正併發標記期間因用戶程序繼續運做而致使標記產生變更的那一部分對象的標記記錄,這個階段的停頓時間通常會比初始標記階段稍長一些,但比並發標記時間短;
  • 併發清除:標記-清除算法;

  整個過程當中耗時最長的併發標記和併發清除過程收集器線程均可以與用戶線程一塊兒工做,因此,從整體上來講,CMS收集器的內存回收過程是與用戶線程一塊兒併發執行的。
  CMS是一款優秀的收集器,它的主要優勢是:併發收集、低停頓,但他有如下3個明顯的缺點:

  1. CMS收集器對CPU資源很是敏感,在併發階段,它雖然不會致使用戶程序變慢,可是會由於佔用了一部分線程(或者說CPU資源)而致使應用程序變慢,總吞吐量會下降;
  2. CMS收集器沒法處理浮動垃圾(Floating Garbage),可能出現」Concurrent Mode Failure「失敗而致使另外一次Full GC的產生。因爲在併發清理階段用戶線程還在運行,因此還會有新的垃圾不斷產生,這部分並無被標記,也就沒法被本次垃圾回收處理掉,只能等待下一次GC;
  3. CMS是基於」標記-清除「算法實現的收集器,這就意味着收集結束時會有大量空間碎片產生。空間碎片過多時,將會給大對象分配帶來很大麻煩,每每出現老年代還有很大空間剩餘,但沒法找到足夠大的連續空間來分配當前對象,不得不提早觸發一次Full GC;

G1收集器:


  是目前最刁的收集器技術之一,G1是一款面向服務端應用的垃圾收集器。它的使命是在將來能夠替換掉JDK1.5中發佈的CMS收集器。與其餘GC收集器相比,G1具有以下特色:

  • 並行與併發:G1能充分利用多CPU、多核環境下的硬件優點,使用多個CPU(或者CPU核心)縮短Stop-The-World停頓的時間,部分其它收集器本來須要停頓Java線程執行的GC動做,但G1收集器仍然能夠經過併發的方式讓Java程序繼續執行。
  • 分代收集:G1能夠不須要其它收集器配合就能獨立管理整個GC堆,但它可以採用不一樣的方式去處理新建立的對象和已經存活了一段時間、熬過屢次GC的舊對象以獲取更好的收集效果。
  • 空間整合:與CMS的」標記-清理「算法不一樣,G1從總體來看是基於」標記-整理「算法實現的收集器,從局部上看是基於」複製「算法實現的,這兩種算法都意味着G1運做期間不會產生內存空間碎片,收集後能提供規整的可用內存。這種特性有利於程序長時間運行,分配大對象時不會由於沒法找到連續內存空間而提早觸發下一次GC。
  • 可預測的停頓:這是G1相對於CMS的另外一大優點,下降停頓時間是G1和CMS共同的關注點,但G1除了追求低停頓外,還能創建可預測的停頓時間模型,能讓使用者明確指定一個長度爲M毫秒的時間片斷內,消耗在垃圾收集上的時間不得超過N毫秒,這幾乎已是實現Java(RTSJ)的垃圾收集器的特徵了。

  在G1以前的其它收集器進行收集的範圍都是整個新生代或者老年代,而G1再也不是這樣。使用G1時,Java堆得內存佈局就與其它收集器有很大差異,它將整個Java堆劃分爲多個大小相等的獨立區域,雖然保留新生代和老年代的概念,但新生代和老年代再也不是物理隔離的了,它們都是一部分Region(不須要連續)的集合。
G1收集器之因此能創建可預測的停頓時間模型,是由於它能夠有計劃地避免在整個Java堆中進行全區域的垃圾收集。G1跟蹤各個Region裏面的垃圾堆積的價值大小(回收所得到的空間大小以及回收所需時間的經驗值),在後臺維護一個優先列表,每次根據容許的收集時間,優先回收價值最大的Region(這也就是Garbage-First名稱的來由)。這種使用Region劃份內存空間以及有優先級的區域回收方式保證了G1收集器在有限的時間內能夠獲取儘量高的收集效率
G1收集器的運做分爲如下幾個步驟:

  1. 初始標記
  2. 併發標記
  3. 最終標記
  4. 篩選回收
相關文章
相關標籤/搜索