問題:請講下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時間,完成后台的計算任務。綜上,如果是和用戶交互的系統,請選擇以減少停頓時間為目的的垃圾回收器,如果是后台的定時任務等耗時的計算任務,請選擇以提升吞吐量為目的的垃圾回收器。
推薦閱讀
《java面試一日一題:再談垃圾回收器中的串行、並行、並發》