JVM垃圾收集器總結

方塊人發表於2019-05-29

前言:

  瞭解了JVM垃圾回收演算法之後就要說說垃圾收集器了。

一、三個概念

Stop-the-World:JVM執行任何一種GC演算法時是會停止應用程式的執行的,所以大多數GC優化都是從減少Stop-the-world發生的時間來提高程式效能。

SafePoint:安全點。在JVM進行可達性分析的時候要在安全點進行,這個點是所有執行緒都被凍結,避免出現分析過程中物件的引用關係還在不斷變化。前面說的程式停止不是隨便停止,而是到達安全點之後再停頓下來。產生安全點的地方有:方法呼叫,迴圈跳轉,異常跳轉等

二、年輕代區的垃圾收集器

1、Serial收集器

  單執行緒收集器,進行垃圾收集的時候必須暫停其他所有工作執行緒,直到收集結束。對於執行在client模式下的虛擬機器是個很好的選擇。可以通過設定-XX:+UseSerialGC進行使用,使用的是複製演算法回收。

2、ParNew收集器

  使用多條執行緒進行垃圾收集,其餘行為和Serial收集器一樣,可以和CMS收集器配合工作。可以通過設定-XX:+UseParNewGC進行使用,一般使用在server模式下。使用的是複製演算法回收。

3、Parallel Scavenger收集器

  前面兩個收集器在於關注使用者執行緒停頓時間,而這個收集器關注點在於達到一個可控的吞吐量【吞吐量=執行使用者程式碼時間/(執行使用者程式碼時間+垃圾收集時間)】,適合在後臺運算不需要太多互動的任務。可以通過設定-XX:+UseParallelGC進行使用,是在server模式下的預設收集器。使用的是複製演算法回收。

三、老年代區的垃圾收集器

1、Serial Old收集器

單執行緒收集器,進行垃圾收集的時候必須暫停其他所有工作執行緒,直到收集結束。client模式下的虛擬機器預設的老年代收集器。可以通過設定-XX:+UseSerialOldGC進行使用,使用的是標記-整理演算法回收。

2、Parallel Old收集器

  配合年輕代為Parallel Scavenger收集器使用的,行為都與Parallel Scavenger收集器差不多隻是演算法不一樣。同樣適合在後臺運算不需要太多互動的任務。可以通過設定-XX:+UseParallelOldGC進行使用。使用的是標記-整理演算法回收。

3、CMS收集器

  是一種以獲取最短回收停頓時間為目標的收集器,可以通過設定-XX:+UseConcMarkSweepGC進行使用。基於標記-清除演算法。運動過程有6個步驟:

  初始標記:需要虛擬機器進行stop-the-world,僅標記一下GC Roots所能連線到的物件

  併發標記:進行GC Roots 追蹤的過程,這時候程式不會停頓

  併發預清理:查詢執行併發標記階段從年輕代進入老年代的物件。

  重新標記:進行stop-the-world,掃描CMS堆中的剩餘物件

  併發清除:清理垃圾物件,程式不會停頓

  併發重置:重置CMS收集器的資料結構

  使用這個收集器使得使用者程式能在執行的時候進行清理垃圾物件。在清理過程中產生的垃圾物件會由下一次再回收。但是由於使用的是標記-清除演算法,容易使得記憶體碎片化。

4、G1收集器

  這是一個既用於年輕代也用於老年代的收集器。使用G1收集器時Java堆就會與使用其他收集器的佈局不同。它是將整個Java堆記憶體劃分為多個大小相等的Region,這樣年輕代和老年代就不再物理隔離。

 

  可以通過設定-XX:+UseG1GC進行使用,使用的是複製+標記-整理演算法回收。這樣就不會出現記憶體碎片化。

  具備如下特點:

  並行與併發,使用多個CPU來縮短stop-the-world的停頓時間,這樣在GC的時候不需要停頓Java執行緒。使得GC和使用者執行緒併發執行。

  分代收集:G1是存在於年輕代和老年代的收集器。年輕代使用負責演算法,老年代使用收集器。

  空間整合。是基於標記-整理的演算法實現的。可以解決記憶體碎片的問題。

  可預測的停頓。能讓使用者明確指定在一個長度為M毫秒的時間片段內。

總結

  這個其實只是針對不同場景進行選擇收集器,只需要瞭解收集器適用的場景和作用。具體的演算法之前已經介紹過。

 

相關文章