問題:請講下java中垃圾回收器有哪些?
分析:該問題主要考察hotspot虛拟機下實作的垃圾回收器
回答要點:
主要從以下幾點去考慮,
1、垃圾回收器的種類
2、每種垃圾回收器的着重點是什麼
前邊的文章中分享了“如何設計一個垃圾回收器”、“垃圾回收算法”、“垃圾回收中的并行并發”等,今天打算分享下hotspot虛拟機中的垃圾回收器。
先看下垃圾回收器的分類,分類标準有按照垃圾回收線程和使用者線程的關系、工作的記憶體區域
垃圾回收線程和使用者線程的關系
串行
serial、serial old
并行
parNew、parallel Scavenge、parallel old
并發
CMS、G1
工作的記憶體區域
年輕代
serial、parNew、parallel Scavenge
年老代
serial old、parallel old、CMS
年輕代、年老代
G1
有了上面的分類,對hotspot虛拟機下的垃圾回收器大緻有了了解,下面重點介紹。
serial
serial使用複制算法,作用在年輕代。同時垃圾回收線程是單線程的,也就是串行回收。以減少系統的停頓時間為目的。
serial old
serial old使用标記-整理算法,作用在年老代。垃圾回收線程是單線程,是串行回收。它是serial的年老代版本。以減少系統的停頓時間為目的
parNew
parNew使用複制算法,作用在年輕代。垃圾回收線程是多線程的,是并行回收。它可以相當于serial的多線程版本。以減少系統的停頓時間為目的
parallel Scavenge
parallel Scavenge使用複制算法,作用在年輕代。垃圾回收線程是多線程的,是并行回收。以控制系統的吞吐量為目的,适合背景計算型的任務。
parallel old
parallel Old使用标記-整理算法,作用在年老代。垃圾回收線程是多線程的,是并行回收的,是parallel Scavenge的年老代版本。
CMS
CMS使用标記-清除算法,作用在年老代。垃圾回收是多線程的,且和使用者線程是并發執行的。以擷取最少的系統停頓時間為目的。收集的過程如下,
- 初始标記
- 并發标記
- 重新标記
- 并發清除
示意圖如下,

在上面的4個階段中,初始标記和重新标記都存在stop the world的現象,前者是單線程串行,後者是多線程并行,在并發标記和并發清除階段則屬于并發執行。由于使用的是标記-清除算法,是以在垃圾回收後會存在垃圾碎片的情況;由于是在并發清除階段使用者線程還在運作中,是以會存在浮動垃圾無法回收的情況,
G1
G1作為一款主流的垃圾回收器,從整體上而言使用的是标記-整理算法,具體到每兩個region使用的是複制算法,具有以下的特點,
- 充分利用并行與并發的優勢
- 分代收集,在G1中仍然保持着分代收集的概念,但是不需要搭配其他收集器,它自己就可以管理整個堆,而且年輕代和年老代不再是實體隔離的,取而代之的是把整個堆分為很多大小相等的獨立區域,稱為region,年輕代就是一組region的集合。
- 空間整合,由于從整體上看使用标記-整理算法,從每兩個region上看使用複制算法,是以使用G1不會産生垃圾碎片。
- 可預測的停頓時間,G1和CMS都是以減少停頓時間為目的,和CMS不同的是G1建立了一套可預測的停頓時間模型。
G1分為以下幾個階段
- 初始标記
- 并發标記
- 最終标記
- 篩選回收
示意圖如下,
除了上面介紹的7款垃圾回收器外,現在還有一個ZGC,是比較新的垃圾回收器,這個計劃後續再研究。
衡量一款垃圾回收器的好壞,主要看兩個關鍵名額:停頓時間、吞吐量。針對這兩個名額的解釋,可以參見《java面試一日一題:如何設計一款垃圾回收器》。
停頓時間重點關注使用者線程的停頓時長,主要影響的是和使用者的互動上,反應在系統的響應速度;吞吐量則關注的是高效利用CPU時間,完成背景的計算任務。綜上,如果是和使用者互動的系統,請選擇以減少停頓時間為目的的垃圾回收器,如果是背景的定時任務等耗時的計算任務,請選擇以提升吞吐量為目的的垃圾回收器。
有不正之處,歡迎指正,謝謝