JVM垃圾收集器

若是說垃圾收集算法是內存回收的方法論,那麼垃圾收集器就是內存回收的具體實現,這裏討論一下基於JDK1.7 以後的HotSpot 虛擬機所包含的垃圾收集器,先來一張圖:
JVM垃圾收集器算法

這張圖中兩個收集器之間存在的連線,就說明他們能夠搭配使用,虛擬機所處的區域,則表示他是屬於新生代收集器仍是老年代
收集器。服務器

從JDK1.3以前都在用Serial收集器,一直到如今JDK 1.7,HotSpot 虛擬機開發團隊爲消除或者減小工做線程因內存回收兒致使停頓的努力一在進行着,從Serial收集器到Parallel收集器
再到ConcurrentMarkSweep (CMS ) 乃至GC收集器最前沿的成果Garbage First (G1) 收集器,一直致力於用戶線程的停頓時間不短縮短,可是依舊沒有辦法徹底消除。多線程

1.  Serial 收集器
                Serial 收集器是最基本,發展歷史最悠久的收集器,曾經在JDK1.3以前是虛擬機新生代收集的惟
一選擇。他是一個單線程的收集器,在他進行垃圾收集的時候,必須暫停其餘全部的工做線程,直到它收集結束。
Stop The World 是對它的一個最好的描述了,下圖是Serial收集器的運行過程:

JVM垃圾收集器

可是他依然是虛擬機在Client模式下的默認新生代收集器,他也有着優於其餘收集器的地方:簡單而高效(與其餘單線程的收集器相比) ,對於限定單個CPU的環境來講,Serial收集器因爲沒有線程
交互的開銷,天然能夠提升單線程收集效率。因此Serial收集器對於運行在Client模式下的虛擬機來講是一個很好的選擇。併發

2. PraNew收集器

他是Serial收集器的多線程版本,除了使用多線程進行垃圾收集以外,其他包括收集算法,Stop The World ,對象分配規則,回收策略等都與Serial 收集器徹底同樣。
下圖是PraNew收集器的工做過程:
JVM垃圾收集器
目前只有它能和CMS收集器配合工做,ParNew 收集器也是使用-XX:+UseConcMarkSweepGC 選項後的默認新生代收集器,也可使用-XX:UsePraNewGC選項強制指定他。
他默認開啓的收集線程數量與CPU的數量相同,在CPU很是多的環境下,可使用-XX:ParallelGCThreads參數來限制垃圾收集的線程數。ide

3. Parallel Scavenge 收集器

Parallel Scavenge 收集器是一個新生代收集器,他也是使用複製算法的收集器,又是並行的多線程收集器。Parallel Scavenge 收集器的特色是他的兩個關注點與其餘的收集器不一樣
,CMS收集器關注點是儘量縮短卡機收集器時候,用戶線程的停頓時間,而Parallel Scavenge 收集器的目的是達到一個可控制的吞吐量。
吞吐量=運行用戶代碼時間/(運行用戶代碼時間+垃圾收集時間)
主要適合在後臺運算而不須要太多交互的任務。
Parallel Scavenge 收集器提供了兩個參數用於精確控制吞吐量,分別是:控制最大垃圾收集停頓的時間(-XX:MaxGCPauseMilis)參數以及直接設置吞吐量大小(-XXGCTimeRatio)參數
不過你們不要認爲若是把「最大垃圾收集停頓的時間」參數設置小一點就可使得垃圾收集速度變得更快,GC停頓時間縮短是以犧牲吞吐量和新生代空間來換取的。性能

4.Serial Old 收集器

Serial Old 是Serial收集器的老年代版本,他一樣是個單線程收集器,使用「標記整理」算法。這個收集器的主要意義也是給Client模式下的虛擬機使用。
Serial Old 收集器的運行示意圖以下:
JVM垃圾收集器線程

5. Parallel Old 收集器

Parallel Old 是Parallel Scavenge收集器的老年代版本,使用多線程和「標記-整理」算法。他是在JDK1.6纔開始提供的,在此以前,新生代的Parallel Scavenge收集器一直處於
比較尷尬的狀態,緣由是,若是新生代選擇了Parallel Scavenge 收集器,老年代除了Serial Old 收集器以外別無選擇。因爲老年代Serial Old 收集器在服務端應用性能上的「拖累"
使用了Parallel Scavenge 收集器也未必能在總體應用上 得到吞吐量最大的效果,因爲單線程的老年代收集中沒法充分利用服務器多CPU的處理能力,在老年代很大並且硬件
比較高級的環境中,這種組合的吞吐量甚至還不必定有ParNew 加上CMS的組合給力。直到Parallel Old 收集器出現後,吞吐量有線收集器終於有了名副其實的組合,在注重吞吐量以及
CPU資源敏感的場合,均可以有線考慮Parallel Scavenge 加Parallel Old 收集器,Parallel Old 收集器工做過程如圖:
JVM垃圾收集器code

6. CMS 收集器

CMS(Concurrent Mark Sweep) 收集器是一種以獲最短回收停頓時間爲目標的收集器。從名字(Mark Sweep )上就能夠看出,CMS 是基於「標記-清除」算法 實現的,他的運做過程相對於
前面幾種收集器來講更復雜一些,整個過程分爲4個步驟:對象

  • 初始標記(CMS initial mark)
  • 併發標記(CMS concurrent mark)
  • 從新標記(CMS remark)
  • 併發清除(CMS concurrent sweep)

其中,初始標記,從新標記這兩個步驟「Stop The World」。 初始標記僅僅只是標記一下GC Roots 能直接關聯到的對象,速度很快,併發標記階段就是進行
GC Roots Trcing的過程,而從新標記階段則是爲了修正併發標記期間因用戶程序繼續運做而致使標記產生變更的那一部分對象的標記記錄,這個階段的停頓時間通常
會比初始標記階段稍長一些,可是比並發標記的時間短。CMS 收集器運行示意圖以下:blog

JVM垃圾收集器

7. G1 收集器

G1 是一款面向服務端應用的垃圾收集器,HotSpot 開發團隊賦予他的使命是將來能夠替換JDK1.5中的CMS收集器,G1 具有如下特色:

  • 並行與併發:G1 能充分利用多CPU,多核環境下的硬件優點,使用多個CPU來縮短Stop The World 停頓的
    時間部分其餘收集器本來須要停頓Java線程執行的GC動做,G1收集器仍然能夠經過併發的方式讓Java程序繼
    續執行。

    • 分代收集:他可以採用不一樣的方式去處理新建立的對象和已經存活了一段時間,熬過屢次GC的就對象以獲取
      更好的收集效果。
    • 空間整合:與CMS的標記清除算法不一樣,G1從總體看來是基於 標記-整理算法實現的,但從局部看來基於復
      制算法實現的。但不管如何,這兩種算法都意味着G1運做期間不會產生內存空間碎片,手機後能提供規整的
      可用內存。
    • 可預測的停頓:G1 還能創建可預測的停頓時間模型,能讓使用者明確指定在一個長度爲M毫秒的時間片斷內,
      消耗在垃圾收集上的時間不得超過N毫秒。

      G1 收集器運行示意圖以下:

JVM垃圾收集器

相關文章
相關標籤/搜索