java中jvm垃圾收集器簡單介紹
jvm垃圾收集器(新生代)
serial收集器
serial收集器是最基本、發展歷史最悠久的收集器,jdk1.3.1之前是新生代收集的唯一選擇。採用複製演算法。這個收集器是單執行緒收集器,它在進行垃圾收集時,必須暫停其他所有的工作執行緒,直到它收集結束(stop the world)。它依然是虛擬機器允許在client模式下的預設新生代收集器。它有著優於其他收集器的地方:簡單而高效,對於限定單個cpu的環境來說,它沒有執行緒互動的開銷,專心做垃圾收集自然可以獲得最高的單執行緒收集效率。
parnew收集器
parnew收集器其實是serial收集器的多執行緒版本,除了使用多執行緒進行垃圾收集之外,其餘行為包括serial收集器的可用的所有控制引數,收集演算法,stop the world,物件分配規則,回收策略等,都與serial收集器完全一致,實現上,這兩種收集器共用了很多程式碼。除了多執行緒之外,其他與serial收集器相比並沒有太多創新之處,但它卻是許多執行在server模式下的虛擬機器中首選的新生代收集器,其中重要的原因是,除了serial收集器之外,目前只有它能與cms收集器配合工作。cms收集器是jdk1.5時期,hotspot推出的一款在強互動應用中幾乎可認為有劃時代意義的垃圾收集器
parnew收集器在單cpu環境中絕對不會比serial收集器有更好的效果。隨著cpu數量增加,它對於gc時系統資源的有效利用還是有好處的,它預設開啟的收集執行緒數與cpu的數量相同,可以使用-XX:ParallelGCThreads引數來限制垃圾收集的執行緒數。
Parallel Scavenge收集器
Parallel Scavenge收集器是一個新生代收集器,它使用複製演算法的收集器,又是並行的多執行緒收集器,看上去和parnew都一樣。
Parallel Scavenge收集器的特點是它的關注點與其他收集器不同,cms等收集器的關注點是儘可能地縮短垃圾收集時使用者執行緒的停頓時間,而Parallel Scavenge收集器的目標則是達到一個可控制的吞吐量。所謂吞吐量就是cpu用於執行使用者程式碼的時間與cpu總消耗時間的比值。停頓時間越短就越適合需要與使用者互動的程式,良好的響應速度能提升使用者體驗,而高吞吐量則可以高效利用cpu時間,儘快完成程式的運算任務,主要適合在後臺運算而不需要太多互動的任務。自適應調解策略也是Parallel Scavenge收集器與parnew收集器的一個重要區別。
jvm垃圾收集器(老年代)
serial old收集器
serial old收集器是serial收集器的老年代版本,同樣是一個單執行緒收集器,使用標記-整理演算法,主要是給client模式下的虛擬機器使用。如果是server模式下,兩大用途:一種用途是在jdk1.5及之前版本與Parallel Scavenge收集器搭配使用,另外一種用途是作為cms收集器的後備預案,在併發收集發生concurrent mode failure時使用。
Parallel old收集器
Parallel old收集器是Parallel Scavenge收集器的老年代版本,使用多執行緒和標記-整理演算法,這個收集器在jdk1.6中才開始提供,在此之前,新生代的Parallel Scavenge收集器一直處於比較尷尬的狀態。原因是,如果新生代選擇Parallel Scavenge收集器,老年代除了serial old收集器外別無選擇。
cms收集器
cms收集器是基於標記-清除演算法實現的。cms收集器是一種以獲得最短回收停頓時間為目標的收集器。目前很大一部分的java應用幾種在網際網路站或者b/s系統的服務端上,這類應用尤其重視服務響應速度,希望系統停頓時間最短,以給使用者帶來較好的體驗。cms收集器非常符合這類應用的需求。
它的運作過程相對於前面的幾種收集器來說相對複雜,整個過程分為4個步驟,初始標記,併發標記,重新標記,併發清除,其中初始標記、重新標記這兩個步驟仍然需要stop the world,初始標記僅僅只是標記一下gc roots能直接關聯到的物件,速度很快,併發標記階段就是進行gc roots tracing的過程,重新標記階段則是為了修正併發標記期間使用者程式繼續執行而導致標記產生變動的那部分物件的標記記錄,這個階段的停頓時間一般會比初始標記的階段稍長一些,但遠比並發標記時間短。
cms收集器缺點:cms收集器對cpu欄位非常敏感、cms收集器無法處理浮動垃圾、cms基於標記-清除演算法實現,收集結束時會有大量的空間碎片產生。
G1收集器
G1收集器是當今收集器技術發展的最前沿成果之一,直到jdk7u4,sun公司才認為它達到足夠成熟的商用程度。
在G1之前的其他收集器的範圍都是整個新生代和老年代,G1不再是這樣。它將整個java堆劃分為多個大小相等的獨立區域,雖然還保留有新生代和老年代的概念,但新生代和老年代不再是物理隔離的了,它們都是一部分region(不需要連續)的集合。
G1收集器之所以能建立可預測的停頓時間模型,是因為它可以有計劃的避免在整個java堆中進行全區域的垃圾收集。G1跟蹤各個region裡面的垃圾堆積的價值大小,在後臺維護一個優先順序列表,每次根據允許的收集時間,優選回收價值最大的region。這種使用region劃分記憶體空間以及有優先順序的區域回收方式,保證了G1收集器在有限的時間內可以獲取儘可能高的收集效率。