垃圾回收器
按線程數分類
- 串行垃圾回收器
- 串行回收是在同一時間段內只允許有一個CPU用于執行垃圾回收操作,此時工作線程被暫停,直至垃圾收集工作結束
- 在諸如單CPU處理器或者較小的應用內存等硬件平臺不是特別優越的場合,串行回收器的性能表現可以超過并行回收器和并發回收器。所以,串行回收默認被應用在客戶端的Client模式下的JVM中
- 在并發能力比較強的CPU上,并行回收器產生的停頓時間要短于串行回收器
- 和串行回收相反,并行收集可以運用多個CPU同時執行垃圾回收,因此提升了應用吞吐量,不過并行回收仍然與串行一樣,采用獨占式,使用了“Stop-The-world”機制
- 并行垃圾回收器
按工作模式
- 并發式垃圾回收器
并發式垃圾回收器與應用線程交替工作,以盡可能減少應用程序的停頓時間 - 獨占式垃圾回收器
獨占式垃圾回收器一旦運行,就停止應用程序中的所有用戶線程,直到垃圾回收過程完全結束
按碎片處理方式
- 壓縮式垃圾回收器
- 壓縮式垃圾回收器會在回收完成后,對存活對象進行壓縮整理,消除回收后的碎片----再分配對象空間使用:指針碰撞
- 非壓縮式垃圾回收器
- 再分配對象使用:空閑列表
按工作內存區間分
- 年輕代垃圾回收器
- 老年代垃圾回收器
評估GC性能指標
- 吞吐量:運行用戶代碼的時間占總運行時間的比例(總運行時間:程序運行時間+內存回收時間)
- 暫停時間:執行垃圾收集時,程序的工作線程被暫停的時間
- 垃圾收集開銷:吞吐量的補數,垃圾收集所用時間與總運行時間的比例
- 收集頻率:相對于應用程序的執行,收集操作發生的頻率
- 內存占用:Java堆區所占的內存大小 - 快速:一個對象從誕生到被回收所經歷的時間
注: - 上述加粗三項共同構成了一個“不可能三角”,三者總體的表現會隨著技術進步而越來越好,一款優秀的收集器通常最多同時滿足其中的兩項
- 這三項里,暫停時間的重要性日益凸顯。因為隨著硬件發展,內存占用多些越來越能容忍,硬件性能的提升也有助于降低收集器運行時對應用程序的影響,即提高了吞吐量。而內存的擴大,對延遲反而帶來負責效果
- 簡單說,主要抓兩點即吞吐量和暫停時間
吞吐量
- 吞吐量是CPU用于運行用戶代碼的時間與CPU總消耗時間的比值,即吞吐量 = 運行用戶代碼時間/(運行用戶代碼時間 + 垃圾收集時間)
- 比如,虛擬機總共運行了100分鐘,其中垃圾回收花掉1分鐘,那吞吐量99%
- 應用程序能容忍較高的暫停時間,因此,高吞吐量的應用程序有更長的時間基準,快速響應是不必考慮的
- 吞吐量優先,意味著單位時間內,STW的時間最短0.2 + 0.2 = 0.4
暫停時間
- 暫停時間是指一個時間段內應用程序線程暫停,讓GC線程執行的狀態
- 暫停時間優先,意味著盡可能讓單次STW的時間最短:0.1+0.1+0.1+0.1+0.1=0.5
吞吐量VS暫停時間
- 高吞吐量較好因為應用程序的最終用戶感覺只有應用程序線程在做生產性工作,直覺上,吞吐量越高程序運行越快
- 低暫停時間較好因為從最終用戶的角度來看不管是GC還是其他原因導致一個應用被掛起始終是不好的,這取決于應用程序的類型,有時候甚至短暫的200ms暫停都可能打斷終端用戶體驗,因此,具有低的較在暫停時間是非常重要的,特別對于一個交互式應用程序
- 高吞吐量和低暫停時間是一對相互競爭的目標(矛盾)
- 如果選擇以吞吐量優先,那么必然需要降低內存回收的執行頻率,但是這樣會導致GC需要更長的暫停時間來執行內存回收
- 如果選擇低延遲優先,那么為了降低每次執行內存回收時的暫停時間,只能頻繁地執行內存回收,這又引起了年輕代內存的縮減和導致程序吞吐量下降
注:現在標準–在最大吞吐量優先的情況下,降低停頓時間
經典垃圾收集器
- 串行垃圾收集器:Serial、Serial Old
- 并行垃圾收集器:ParNew、Parallel Scavenge、Parallel Old
- 并發垃圾回收器:CMS、G1
查看默認的垃圾收集器
- -XX:+PrintCommandLineFlags:查看命令行相關參數(包含使用的垃圾收集器)
- 使用命令行指令:jinfo -flag 相關垃圾回收器參數 進程ID
Serial回收器:串行回收
- Serial收集器是最基本、歷史最悠久的收集器JDK1.3之前新生代唯一的選擇
- Hotpot中Client模式下的默認新生代垃圾收集器
- 采用復制算法,串行回收“Stop-the-world”機制的方式執行內存回收
- 除了年輕代之外,Serial收集器還提供用于執行老年代垃圾收集的Serial Old收集器,Serial Old收集器同樣采用了串行回收和“Stop-the-world”機制,只不過內存回收算法使用的是標記-壓縮算法
- Serial Old是運行在Client模式下的默認老年代垃圾回收器
- Serial Old在Server模式下有兩個用途①與新生代Parallel Scavenge配合使用②作為老年代CMS收集器的后備垃圾收集方案
- 優勢:簡單而高效,對于限定單個CPU的環境來說,Serial由于沒有線程交互的開銷,專心做垃圾收集
- 在用戶的桌面應用場景中,可用內存一般不大,可以在較短時間內完成垃圾收集,只要不頻繁發生,使用串行回收器可以接受
- 在Hotspot虛擬機中,使用-XX:+UseSerialGC參數可以指定年輕代和老年代都使用Serial
注:Serial收集器是一個單線程收集器,單線程不僅僅說明它只會使用一個CPU或一條收集線程去完成垃圾收集工作,更重要的是在它進行垃圾收集時,必須暫停其他所有的工作線程,直到它收集結束(Stop The World)
待續… …