1. 程式人生 > >想買保時捷的運維李先生學Java效能之 垃圾收集器

想買保時捷的運維李先生學Java效能之 垃圾收集器

前言

垃圾收集演算法是記憶體回收的方法論;垃圾收集器是記憶體回收的具體實現。Java虛擬機器規範中對垃圾收集器應該如何實現並沒有任何規定,因此不同的廠商、不同版本的虛擬機器所提供的垃圾收集器都有很大的差別,並且一般都會提供引數供使用者根據自己的應用特點和要求組合出各個年代所使用的收集器。   虛擬機器裡並不是使用一個收集器,而是很多收集器搭配使用,在不同的年代使用不同的收集器。

 

 

一、Serial收集器

Serial收集器是最基本、發展歷史最悠久的收集器、曾經是虛擬機器新生代收集的唯一選擇。這個收集器是一個單執行緒的收集器,但它的“單執行緒”的意義並不僅僅說明它只會使用一個CPU或一條收集執行緒去完成垃圾收集工作,更重要的是在他進行垃圾收集時,必須暫停其他所有的工作執行緒,直到他收集結束。“Stop-The-World”這項工作實際是是由虛擬機器在後臺自動發起和自動完成的,在使用者不可見的情況下把使用者正常工作的執行緒全部停掉,這是比較難以接受的。  

 

 

 

二、ParNew收集器

ParNew收集器就是Serial收集器的多執行緒版本,處理使用多條執行緒進行垃圾收集之外,其餘行為包括Serail收集器可用的所有控制引數(例如:-XX:SurvivorRatio、-XX:PretenureSizeThreshold、-XX:HandlePromotionFailure等)、收集演算法、Stop the World、物件分配規則、回收策略等都與Serail收集器完全一致,在實現上,兩者也共用了很多程式碼。

 

 

ParNew收集器除了多執行緒收集之外,其他與Serial收集器相比並沒有多大的創新之處,但它卻是許多執行在Server模式下的虛擬機器中首選的新生代收集器,其中有一個與效能無關但很重要的原因是,除了Serial收集器外,目前只有它能與CMS收集器配合工作。  

三、Paraller Scanvenge收集器

Paraller Scanvenge收集器是一個新生代收集器,它也是使用複製演算法的收集器,又是並行的多執行緒收集器。   Paraller Scanvenge收集器的特點是它的關注點與其他收集器不同,CMS等收集器的關注點是儘可能的縮短垃圾收集器收集時使用者現程的停頓時間,而Paraller Scavenge收集器的目標這是達到一個可控制的吞吐量(Throughput)。所謂吞吐量就是CPU用於執行使用者程式碼的時間與CPU總消耗時間的比值。即吞吐量=執行使用者程式碼時間/(執行使用者程式碼時間 + 垃圾收集時間)。   停頓時間越短越適合需要與使用者互動的程式,良好的響應速度能提升使用者體驗,而高吞吐量則可以高效率的利用CPU時間,儘快的完成程式的運算任務,主要適合在後臺運算而不需要太多互動的任務。   parallel Scavenge收集器提供了兩個引數用於精確控制吞吐量,分別是控制最大垃圾收集器停頓時間的-XX:MaxGCPauseMillis引數以及直接設定吞吐量大小的-XX:GCTimeRatio引數。   MaxGCPauseMillis 引數允許的值是一個大於0的毫秒數,收集器將盡可能地保證記憶體回收花費的時間不超過設定值。 GCTimeRatio引數的值應當是一個大於0且小於100的整數,也就是垃圾收集時間佔比總時間的比率。   注: 並行(Paraller):指多條來及收集執行緒並行工作,但此使用者執行緒仍然處於等待狀態 併發(Concurrent):值使用者執行緒與垃圾收集執行緒同時執行(但不一定是並行的,可能會交替執行),使用者程式在繼續執行,而垃圾收集程式執行在另一個CPU上。  

4、Serial Old收集器

Serial Old 收集器是Serial 收集器的老年代版本,它同樣是一個單執行緒收集器,使用“標記-整理”演算法。這個收集器的主要意義也是在與Client模式下的虛擬機器使用。如果在Server模式下,那麼他還有兩大用途,一是在JDK1.5以及之前的版本中與Paraller Scavenge收集器搭配使用,另一種用途是做為CMS收集器的後備預案,在併發收集發生Concurrent Mode Failure時使用。  

 

  

五、parallel Old 收集器

Paraller Old收集器是Paraller Scavenge收集器的老年代版本,使用多執行緒和“標記-整理”演算法。

 

 

6、CMS收集器

  CMS(Concurrent Mark Sweep)收集器是一種以獲取最短回收停頓時間為目標的收集器。CMS收集器是基於“標記-清除”演算法實現的,它的運作過程分為4個步驟:   1)初始標記(CMS initial mark) 2)併發標記(CMS concurrent mark) 3)重新標記(CMS remark) 4)併發清除(CMS concurrent sweep)   其中,初始標記和重新標記這兩個步驟仍然需要“Stop the World”(停止工作執行緒)。初始標記僅僅只是標記一下GC Roots能直接關聯到的物件,速度很快。併發標記階段就是進行GC Roots Tracing的過程,而重新標記階段則是為了修正併發標記期間因使用者程式繼續運作而導致標記產生變動的那一部分物件的標記記錄,這個階段的停頓時間一般會比初始標記階段稍長一些,但遠比並發標記的時間短。  

 

 

 

七、G1(Garbage-First)收集器

G1(Garbage-First)收集器是一款面向服務端應用的垃圾收集器。如果不計算維護Remembered Set的操作,G1收集器的運作大致可以分為以下幾個步驟: 1)初始標記(Initial Marking) 2)併發標記(Concurrent Marking) 3)最終標記(Final Marking) 4)篩選回收(Live Data Counting and Evacuation)  

 

 

  &nbs