Java中的垃圾收集器__Java

來源:互聯網
上載者:User

1. Serial收集器

Serial收集器是一個單線程的收集器,但它的“單線程”的意義並不僅僅是說明它只會使用一個CPU或一條收集線程去完成垃圾收集工作,更重要的是在它進行垃圾收集時,必須暫停其他所有的背景工作執行緒,直到它收集結束。

Serial收集器到現在為止,它依然是JAVA虛擬機器運行在Client模式下的預設新生代收集器。它也有著優於其他收集器的地方:簡單而高效(與其他收集器的單線程比),對於限定單個CPU的環境來說,Serial收集器由於沒有線程互動的開銷,專心做垃圾收集自然可以獲得最高的單線程收集效率。在使用者的案頭應用情境中,分配給虛擬機器管理的記憶體一般來說不會很大,收集幾十兆甚至一兩百兆的新生代(僅僅是新生代使用的記憶體,案頭應用基本上不會再大了),停頓時間完全可以控制在幾十毫秒最多一百多毫秒以內,只要不是頻繁發生,這點停頓是可以接受的。所以,Serial收集器對於運行在Client模式下的虛擬機器來說是一個很好的選擇。

2. ParNer收集器

ParNew收集器是Java虛擬機器中垃圾收集器的一種。它是Serial收集器的多線程版本,除了使用多條線程進行垃圾收集之外,其餘行為包括Serial收集器可用的所有控制參數(例如:-XX:SurvivorRatio、-XX:PretenureSizeThreshold、-XX:HandlePromotionFailure等)、收集演算法、Stop The World、對象分配規則、回收策略等都與Serial收集器一致)

ParNew是許多運行在Server模式下的虛擬機器中首選的新生代收集器,在JDK1.6以及之前的版本中,除了Serial收集器外,只有它能與CMS收集器配合工作。

3. Parallel Scavenge收集器

Parallel Scavenge收集器是一個新生代回收器,它是使用複製演算法的收集器。

Parallel Scavenge收集器的特點是它的關注點與其他收集器不同,CMS等收集器關注點是儘可能的縮短垃圾收集時使用者線程的停頓時間,而Parallel Scavenge收集器的目標則使達到一個可控值的輸送量。所謂輸送量就是CPU運行使用者代碼的時間與CPU總消耗時間的比值,即輸送量 = 運行使用者代碼時間 / (運行使用者代碼時間 + 垃圾收集時間)。虛擬機器總共運行了100分鐘,其中垃圾收集花掉1分鐘,那輸送量就是99%。

Parallel Scanvenge收集器提供了兩個參數用於精確控制輸送量,分別是控制最大垃圾收集器停頓時間的 -XX:MaxGCPauseMillis參數以及直接設定輸送量大小的 -XX:GCTimeRatio。

MaxGCPauseMills參數允許的值時一個大於0的毫秒數,收集器儘可能地保證記憶體回收花費的時間不超過設定值。GC停頓時間縮短是以犧牲輸送量和新生代空間來換取的:系統把新生代調小一些,收集300MB的時間肯定比收集500MB的時間快,這也導致垃圾收集發生得更頻繁一些,原來10秒收集一次,每次停頓100毫秒,現在變成5秒停頓一次,每次停頓70毫秒。停頓的時間的確在下降,但輸送量也下降了。

GCTimeRatio參數的值應當是一個大於0且小於100的整數,也就是垃圾收集時間佔總時間的比率,相當於輸送量的倒數。如果把參數設定為19,那允許的最大GC時間就佔總時間的5%(即1/(1+19)),預設值為99,就是最大允許1%的垃圾收集時間。

Parallel Scavenge收集器還有一個參數-XX:UseAdaptiveSizePolicy。這個一個切換參數,當這個參數開啟以後,就不需要手工指定新生代的小小(-Xmn)、Eden區與Survivor區的比例(-XX:SurvivorRatio)、晉陞老年代的大小(-XX:PretenureSSizeThreshold)等細節參數了,虛擬機器會根據當前系統的運行情況收集效能監控資訊,動態調整這些參數以提供最合適的停頓時間或者最大的輸送量。

4. Serial Old收集器

Serial Old是Serial收集器的老年代版本,它是一個單線程的垃圾收集器,使用“標記-整理”演算法。這個收集器的主要意義也是在於給Client模式下的虛擬機器使用。如果是在Server模式下,那麼它主要還有兩大用途,一種用途是在JDK1.5以及之前的版本中與Parallel Scavenge收集器搭配使用。另一個用途就是作為CMS收集器的後背預案。在並發收集Concurrent Mode Failure時使用。

5. Parallel Old收集器

Parallel Old收集器是Parallel Scavenge收集器的老年代版本,使用多線程和“標記-整理”演算法。這個收集器是在JDK1.6中才開始提供的,在此之前,新生代Parallel Scavenge收集器一直處於比較尷尬的狀態。原因是新生代選擇了Parallel Scavenge收集器,那麼老年代除了選擇Serial Old收集器之外別無選擇。由於老年代Serial Old收集器在服務端應用效能上的“拖累”,使用了Parallel Scavenge收集器也未必能在整體應用上獲得較大輸送量的效果,由於單線程的老年代收集中無法充分利用伺服器多CPU的處理能力。在老年代很大且硬體比較高的環境中,這種組合的輸送量還不一定有ParNew加CMS的組合大。

知道Parallel Old收集器出現後,”輸送量優先”收集器終於有了比較名副其實的應用組合,在注重輸送量以及CPU資源敏感的場合,都可以優先考慮Parallel Scavenage加Parallel Old收集器。

6. CMS收集器

CMS(Concurrent Mark Sweep)收集器是一種以擷取最短回收停頓時間為目標的收集器,它是一個多線程收集器,採用“標記-清除”演算法實現的,它的運作過程相對於前面幾種收集器來說更複雜一些。整過程分為以下4個步驟:

1) 初始標記(CMS inital mark)2) 並發標記(CMS concurrent mark)3) 重新標記(CMS remark)4) 並發清除(CMS concurrent sweep)

其中,初始標記、重新暴擊這兩個步驟仍然需要“Stop The World”。初始標記僅僅是標記一下GC Roots能直接關聯到的對象,速度很快,並發標記階段就是進行GC Roots Tracing的過程,而重新標記截斷則是為了修正並發標記期間因使用者程式繼續運作而導致標記產生變動的那一部分對象的標記記錄,這個階段的停頓時間一般會比初始標記截斷稍長一些,但遠比並發標記時間短。

CMS是一款優秀的收集器,但還是有以下3個明顯的缺點

1) CMS收集器對CPU資源非常敏感。在並發階段,它雖然不會導致使用者線程停頓,但是會因為佔用了一些資源而導致應用程式變慢,總輸送量降低。2) CMS收集器無法處理浮動垃圾,可能出現"Concurrent Mode Failure"失敗而導致另一次Full GC的產生。由於CMS並發清理階段使用者線程還在運行著,伴隨程式運行自然還會有新的垃圾不斷產生,這一部分垃圾出現在標記過程之後,CMS無法再檔次收集過程中處理掉它們。只好留待下一次GC時再清除掉。3) CMS是一款基於"標記-清理"演算法實現的收集器。當收集結束後會有大量的空間片段產生,空間片段過多時,將會給大對象分配帶來麻煩,WangWang老年代還有很大空間剩餘,但是無法找到足夠大的連續空間來分配當前對象,不得不提前觸發一次Full GC。

7. G1收集器

G1是一款面向服務端應用的垃圾收集器。與其他收集器相比,G1具備以下特點:

1) 並行與並發:G1能充分利用多CPU、多核環境下的硬體優勢、使用多個CPU來縮短Stop-The-World停頓的時間,部分其他收集器原本需要停頓Java線程執行GC動作,G1收集器仍然可以通過並發地方式讓Java程式繼續執行。2) 分代收集:與其他收集器一樣,分代概念在G1中依然保留。誰然G1可以不需要其他收集器獨立整理整個GC對,但它能夠採用不同的方式來處理新建立的對象和已經存活了一段時間、熬過多次GC的舊對象以擷取更高的收集效果。3) 空間整合:與CMS的“標記-清理”演算法不同,G1從整體來看是基於“標記-整理”演算法實現的收集器,從局部(兩個Region之間)上來看是基於“複製”演算法實現的,但無論如何,這兩種演算法都意味著G1運行期間不會產生記憶體空間隨便,收集後能提供規整的可用記憶體。這種特徵有利於程式長時間運行,分配大對象不會因為無法找到練習記憶體空間而提前觸發下一次GC。4) 可預測的停頓:這是G1相對於CMS的另一大優勢,降低停頓時間是G1和CMS共同的關注點,但G1除了追求低停頓外,還能建立可預測的停頓時間模型,能讓使用者明確指定在一個長度為M毫秒的時間片段內,消耗在垃圾收集上的時間不得超過N毫秒,這幾乎已經是即時Java(RTSJ)的垃圾收集器的特徵了。

在G1之前的其他收集器進行收集的範圍都是整個新生代或者老年代,而G1不在是這樣,使用G1收集器時,Java堆的記憶體布局就與其他收集器有很大差別,它將整個Java堆劃分為多個大小相等的獨立地區(Region),雖然還保留新生代和老年代的概念,但新生代和老年代已經不再是物理隔離的了,它們都是Region(不需要連續的集合)。

在G1收集中,Region之間的對象引用以及其他收集器的新生代與老年代之間的對象引用,虛擬機器都是使用Remembered Set來避免全堆掃描的。G1中每個Region都有一個與之對應的Remembered Set,虛擬機器發現程式在對Reference類型的資料進行寫操作是,會產生一個Write Barrier暫時中斷寫操作,檢查Reference引用的對象是否處於不同的Region之間(在分代的例子中就是檢查是否老年代中的對象引用了新生代的對象),如果是,便通過CardTable把相關引用資訊記錄到引用對象所屬的Region的Remembered Set之中,當進行記憶體回收是,在GC根節點的枚舉範圍內假如Remembered Set即可保證不對全堆記性掃描也不會有遺漏。

如果不計算維護Remembered Set的操作,G1收集器的運作大致可劃分為以下幾個步驟: 初始標記 並發標記 最終標記 篩選回收

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.