文章目錄
- 1. 綜述
- 2. Serial收集器
- 3. ParNew收集器
- 4. Parallel Scavenge收集器
- 5. Serial Old收集器
- 6. Parallel Old收集器
- 7. CMS收集器
- 8. Garbage First收集器
本文參考于《深入理解Java虛擬機》
1. 綜述
1. 總述:
如果說收集演算法是記憶體回收的方法論,那垃圾收集器就是記憶體回收的實踐者,《Java虛擬機規范》中對垃圾收集器應該如何實作并沒有做出任何規定,因此不同的廠商、不同版本的虛擬機所包含的垃圾收集器都可能會有很大差別,不同的虛擬機一般也都會提供各種引數供用戶根據自己的應用特點和要求組合出各個記憶體分代所使用的收集器,
2. 圖示總述

上圖展示了七種作用于不同分代的收集器,如果
兩個收集器之間存在連線,就說明它們可以搭配使用,圖中收集器所處的區域,則表示它是屬于新生代收集器抑或是老年代收集器,
3. 應用中應如何做出選擇?
雖然我們會對各個收集器進行比較,但并非為了挑選一個最好的收集器出來,雖然垃圾收集器的技術在不斷進步,但直到現在還沒有最好的收集器出現,更加不存在“萬能”的收集器,所以我們選擇的只是對具體應用最合適的收集器,這點不需要多加論述就能證明:如果有一種放之四海皆準、任何場景下都適用的完美收集器存在,HotSpot虛擬機完全沒必要實作那么多種不同的收集器了,
2. Serial收集器
1. 簡介
Serial收集器是最基礎、歷史最悠久的收集器,曾經(在JDK 1.3.1之前)是HotSpot虛擬機新生代收集器的唯一選擇,大家只看名字就能夠猜到,這個收集器是一個單執行緒作業的收集器,但它的“單執行緒”的意義并不僅僅是說明它只會使用一個處理器或一條收集執行緒去完成垃圾收集作業,更重要的是強調在它進行垃圾收集時,必須暫停其他所有作業執行緒,直到它收集結束(“Stop The World”),
2. 圖解作業程序

3.使用的垃圾收集演算法
標記-復制演算法
4. 優點
簡單而高效(與其他收集器的單執行緒相比),對于記憶體資源受限的環境,它是所有收集器里額外記憶體消耗最小的;對于單核處理器或處理器核心數較少的環境來說,Serial收集器由于沒有執行緒互動的開銷,專心做垃圾收集自然可以獲得最高的單執行緒收集效率,
5. 缺點
在垃圾回收程序中會觸發 “Stop The World” 而產生停頓,從而導致用戶體驗不好,
6. 主要應用場景
Serial收集器對于運行在客戶端模式下的虛擬機來說是一個很好的選擇,
3. ParNew收集器
1. 簡介
ParNew收集器實質上是Serial收集器的多執行緒并行版本(新生代收集器),除了同時使用多條執行緒進行垃圾收集之外,其余的行為包括Serial收集器可用的所有控制引數(例如:-XX:SurvivorRatio、-XX PretenureSizeThreshold、-XX:HandlePromotionFailure等)、收集演算法、Stop The World、物件分配規則、回收策略等都與Serial收集器完全一致,在實作上這兩種收集器也共用了相當多的代碼,
2. 圖解作業程序

3. 使用的垃圾收集演算法
標記-復制演算法
4. 補充概念
-
并行:并行描述的是
多條垃圾收集器執行緒之間的關系,說明同一時間有多條這樣的執行緒在協同作業,通常默認此時用戶執行緒是處于等待狀態, -
并發:并發描述的是
垃圾收集器執行緒與用戶執行緒之間的關系,說明同一時間垃圾收集器執行緒與用戶執行緒都在運行,由于用戶執行緒并未被凍結,所以程式仍然能回應服務請求,但由于垃圾收集器執行緒占用了一部分系統資源,此時應用程式的處理的吞吐量將受到一定影響,
5. 主要應用場景
它是許多運行在 Server 模式下的虛擬機的首要選擇,除了 Serial 收集器外,只有它能與 CMS 收集器(真正意義上的并發收集器,后面會介紹到)配合作業,
4. Parallel Scavenge收集器
1. 簡介
Parallel Scavenge收集器也是一款新生代收集器,它同樣是基于標記-復制演算法實作的收集器,也是能夠并行收集的多執行緒收集器,Parallel Scavenge的諸多特性從表面上看和ParNew非常相似,Parallel Scavenge收集器的特點是它的關注點與其他收集器不同,CMS等收集器的關注點是盡可能地縮短垃圾收集時用戶執行緒的停頓時間,而Parallel Scavenge收集器的目標則是達到一個可控制的吞吐量,
2. 補充概念
吞吐量就是處理器用于運行用戶代碼的時間與處理器總消耗時間的比值,

如果虛擬機完成某個任務,用戶代碼加上垃圾收集總共耗費了100分鐘,其中垃圾收集花掉1分鐘,那吞吐量就是99%,
停頓時間越短就越適合需要與用戶互動或需要保證服務回應質量的程式,良好的回應速度能提升用戶體驗;而高吞吐量則可以最高效率地利用處理器資源,盡快完成程式的運算任務,主要適合在后臺運算而不需要太多互動的分析任務,
3. 圖解作業程序

4. 使用的垃圾收集演算法
標記-復制演算法
5. 相關的引數
Parallel Scavenge收集器提供了兩個引數用于精確控制吞吐量,分別是控制最大垃圾收集停頓時間的 -XX:MaxGCPauseMillis 引數以及直接設定吞吐量大小的 -XX:GCTimeRatio 引數,
5. Serial Old收集器
1. 簡介
Serial Old是Serial收集器的老年代版本,它同樣是一個單執行緒收集器,使用標記-整理演算法,
2. 圖解作業程序

3. 使用的垃圾收集演算法
標記-整理演算法
4. 主要的應用場景
供客戶端模式下的HotSpot虛擬機使用,- 在服務端模式下,一種在JDK 5以及之前的版本中
與Parallel Scavenge收集器搭配使用;另外一種就是作為CMS收集器發生失敗時的后備預案,
6. Parallel Old收集器
1. 簡介
Parallel Old是Parallel Scavenge收集器的老年代版本,支持多執行緒并發收集,基于標記-整理演算法實作,
2. 圖解作業程序

3. 使用的垃圾收集演算法
標記-整理演算法
4. 主要的應用場景
注重吞吐量或者處理器資源較為稀缺的場合,都可以優先考慮Parallel Scavenge 加 Parallel Old收集器這個組合,
7. CMS收集器
1. 簡介
CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的收集器,CMS收集器是基于標記-清除演算法實作的,它非常適合在注重用戶體驗的應用上使用,
2. 作業程序
- 初始標記:
標記一下GC Roots能直接關聯到的物件,速度很快 - 并發標記:從GC Roots的直接關聯物件開始遍歷整個物件圖的程序,這個程序耗時較長但是
不需要停頓用戶執行緒,用戶執行緒可以與垃圾收集執行緒一起并發運行, - 重新標記:為了
修正并發標記期間因用戶程式繼續運作而導致標記產生變動的那一部分物件的標記記錄,這個階段的停頓時間通常會比初始標記階段稍長一些,但也遠比并發標記階段的時間短, - 并發清除:
清理洗掉掉標記階段判斷的已經死亡的物件,由于不需要移動存活物件,所以這個階段也是可以與用戶執行緒同時并發的,
3. 圖解作業程序

4. 使用的垃圾收集演算法
標記-清除演算法,
5. 優點
回收停頓時間短,給用戶帶來良好的互動體驗,并發收集
6. 缺點
對處理器資源非常敏感無法處理“浮動垃圾”- 因為CMS收集器是一款基于標記-清除演算法的垃圾收集器,
其收集結束時會有大量空間碎片產生,
7. 主要的應用場景
它非常適合在注重用戶體驗和要求停頓時間短的應用上使用,
8. Garbage First收集器
1. 簡介
G1 (Garbage-First) 是一款面向服務器的垃圾收集器,主要針對配備多顆處理器及大容量記憶體的機器,以極高概率滿足 GC 停頓時間要求的同時,還具備高吞吐量性能特征,G1在后臺維護一個優先級串列,每次根據用戶設定允許的收集停頓時間,優先處理回收價值收益最大的那些Region,這種使用 Region劃分記憶體空間以及有優先級的區域回收方式,保證了 G1 收集器在有限時間內可以盡可能高的收集效率(把記憶體化整為零),
2. 作業程序
- 初始標記:僅僅
只是標記一下GC Roots能直接關聯到的物件,并且修改TAMS指標的值,讓下一階段用戶執行緒并發運行時,能正確地在可用的Region中分配新物件,這個階段需要停頓執行緒,但耗時很短,而且是借用進行Minor GC的時候同步完成的,所以G1收集器在這個階段實際并沒有額外的停頓, - 并發標記:從GC Root開始對堆中物件進行可達性分析,遞回掃描整個堆里的物件圖,
找出要回收的物件,這階段耗時較長,但可與用戶程式并發執行,當物件圖掃描完成以后,還要重新處理SATB記錄下的在并發時有參考變動的物件, - 最終標記:對用戶執行緒做另一個短暫的暫停,
用于處理并發階段結束后仍遺留下來的最后那少量的SATB記錄, - 篩選回收:負責更新Region的統計資料,
對各個Region的回收價值和成本進行排序,根據用戶所期望的停頓時間來制定回收計劃,可以自由選擇任意多個Region構成回收集,然后把決定回收的那一部分Region的存活物件復制到空的Region中,再清理掉整個舊Region的全部空間,這里的操作涉及存活物件的移動,是必須暫停用戶執行緒,由多條收集器執行緒并行完成的,
從上述階段的描述可以看出,G1收集器除了并發標記外,其余階段也是要完全暫停用戶執行緒的,換言之,它
并非純粹地追求低延遲,官方給它設定的目標是在延遲可控的情況下獲得盡可能高的吞吐量,所以才能擔當起“全功能收集器”的重任與期望,
3. 圖解作業程序

4. 特點
- 并行與并發:
- 分代收集
- 空間整合
- 可預測的停頓
5. 使用此收集器下的堆記憶體說明

G1不再堅持固定大小以及固定數量的分代區域劃分,而是把連續的Java堆劃分為多個大小相等的獨立區域(Region),每一個Region都可以根據需要,扮演新生代的Eden空間、Survivor空間,或者老年代空間,收集器能夠對扮演不同角色的Region采用不同的策略去處理,這樣無論是新創建的物件還是已經存活了一段時間、熬過多次收集的舊物件都能獲取很好的收集效果,Region中還有一類特殊的Humongous區域(H),專門用來存盤大物件,G1認為只要大小超過了一個Region容量一半的物件即可判定為大物件,每個Region的大小可以通過引數-XX:G1HeapRegionSize設定,取值范圍為1MB~32MB,且應為2的N次冪,而對于那些超過了整個Region容量的超級大物件,將會被存放在N個連續的Humongous Region之中,G1的大多數行為都把Humongous Region作為老年代的一部分來進行看待,如上圖所示,雖然G1仍然保留新生代和老年代的概念,但新生代和老年代不再是固定的了,它們都是一系列區域(不需要連續)的動態集合,
6. 主要的應用場景
主要使用于服務端模式下的垃圾回收,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/357101.html
標籤:java
