java面試一日一題:java中的垃圾回收器

迷茫中守候發表於2021-06-01

問題:請講下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時間,完成後臺的計算任務。綜上,如果是和使用者互動的系統,請選擇以減少停頓時間為目的的垃圾回收器,如果是後臺的定時任務等耗時的計算任務,請選擇以提升吞吐量為目的的垃圾回收器。

 

有不正之處,歡迎指正,謝謝

 

相關文章