JVM從入門到入土之詳解G1垃圾回收器

前言

文本已收錄至個人GitHub倉庫,歡迎Star:https://github.com/bin392328206/six-finger
種一棵樹最好的時間是十年前,其次是如今
我知道不少人不玩qq了,可是懷舊一下,歡迎加入六脈神劍Java菜鳥學習羣,羣聊號碼:549684836 鼓勵你們在技術的路上寫博客git

絮叨

Garbage First(G1)是垃圾收集領域的最新成果,同時也是HotSpot在JVM上力推的垃圾收集器,並賦予取代CMS的使命。若是使用Java 8/9,那麼有很大可能但願對G1收集器進行評估。本文詳細首先對JVM其餘的垃圾收集器進行總結,並與G1進行了簡單的對比;而後經過G1的內存模型、G1的活動週期,對G1的工做機制進行了介紹;同時還在介紹過程當中,描述了可能須要引發注意的優化點。博主但願經過本文,讓有必定JVM基礎的讀者能儘快掌握G1的知識點。github

JVM GC收集器的回顧與比較

到JDK1.8爲止的垃圾回收器圖以下web

其實他們的一個迭代的過程是隨着技術的演化進行的算法

串行收集器組合 Serial + Serial Old

開啓選項:-XX:+SerialGC安全

串行收集器是最基本、發展時間最長、久經考驗的垃圾收集器,也是client模式下的默認收集器配置。服務器

串行收集器採用單線程stop-the-world的方式進行收集。當內存不足時,串行GC設置停頓標識,待全部線程都進入安全點(Safepoint)時,應用線程暫停,串行GC開始工做,採用單線程方式回收空間並整理內存。單線程也意味着複雜度更低、佔用內存更少,但同時也意味着不能有效利用多核優點。事實上,串行收集器特別適合堆內存不高、單核甚至雙核CPU的場合。多線程

並行收集器組合 Parallel Scavenge + Parallel Old

開啓選項:-XX:+UseParallelGC或-XX:+UseParallelOldGC(可互相激活)併發

並行收集器是以關注吞吐量爲目標的垃圾收集器,也是server模式下的默認收集器配置,對吞吐量的關注主要體如今年輕代Parallel Scavenge收集器上。編輯器

並行收集器與串行收集器工做模式類似,都是stop-the-world方式,只是暫停時並行地進行垃圾收集。年輕代採用複製算法,老年代採用標記-整理,在回收的同時還會對內存進行壓縮。關注吞吐量主要指年輕代的Parallel Scavenge收集器,經過兩個目標參數-XX:MaxGCPauseMills和-XX:GCTimeRatio,調整新生代空間大小,來下降GC觸發的頻率。並行收集器適合對吞吐量要求遠遠高於延遲要求的場景,而且在知足最差延時的狀況下,並行收集器將提供最佳的吞吐量。學習

併發標記清除收集器組合 ParNew + CMS + Serial Old

開啓選項:-XX:+UseConcMarkSweepGC

併發標記清除(CMS)是以關注延遲爲目標、十分優秀的垃圾回收算法,開啓後,年輕代使用STW式的並行收集,老年代回收採用CMS進行垃圾回收,對延遲的關注也主要體如今老年代CMS上。

年輕代ParNew與並行收集器相似,而老年代CMS每一個收集週期都要經歷:初始標記、併發標記、從新標記、併發清除。其中,初始標記以STW的方式標記全部的根對象;併發標記則同應用線程一塊兒並行,標記出根對象的可達路徑;在進行垃圾回收前,CMS再以一個STW進行從新標記,標記那些由mutator線程(指引發數據變化的線程,即應用線程)修改而可能錯過的可達對象;最後獲得的不可達對象將在併發清除階段進行回收。值得注意的是,初始標記和從新標記都已優化爲多線程執行。CMS很是適合堆內存大、CPU核數多的服務器端應用,也是G1出現以前大型應用的首選收集器。

可是CMS並不完美,它有如下缺點:

  1. 因爲併發進行,CMS在收集與應用線程會同時會增長對堆內存的佔用,也就是說,CMS必需要在老年代堆內存用盡以前完成垃圾回收,不然CMS回收失敗時,將觸發擔保機制,串行老年代收集器將會以STW的方式進行一次GC,從而形成較大停頓時間;
  2. 標記清除算法沒法整理空間碎片,老年代空間會隨着應用時長被逐步耗盡,最後將不得不經過擔保機制對堆內存進行壓縮。CMS也提供了參數-XX:CMSFullGCsBeForeCompaction(默認0,即每次都進行內存整理)來指定多少次CMS收集以後,進行一次壓縮的Full GC。

Garbage First (G1)

開啓選項:-XX:+UseG1GC

以前介紹的幾組垃圾收集器組合,都有幾個共同點:

  • 年輕代、老年代是獨立且連續的內存塊;
  • 年輕代收集使用單eden、雙survivor進行復制算法;
  • 老年代收集必須掃描整個老年代區域;
  • 都是以儘量少而快地執行GC爲設計原則。

G1垃圾收集器也是以關注延遲爲目標、服務器端應用的垃圾收集器,被HotSpot團隊寄予取代CMS的使命,也是一個很是具備調優潛力的垃圾收集器。雖然G1也有相似CMS的收集動做:初始標記、併發標記、從新標記、清除、轉移回收,而且也以一個串行收集器作擔保機制,但單純地以相似前三種的過程描述顯得並非很穩當。事實上,G1收集與以上三組收集器有很大不一樣:

  • G1的設計原則是"首先收集儘量多的垃圾(Garbage - First)"。所以,G1並不會等內存耗盡(串行、並行)或者快耗盡(CMS)的時候開始垃圾收集,而是在內部- 採用了啓發式算法,在老年代找出具備高收集收益的分區進行收集。同時G1能夠根據用戶設置的暫停時- 間目標自動調全年輕代和總堆大小,暫停目標越短年輕代空間越小、總空間就越大;
  • G1採用內存分區(Region)的思路,將內存劃分爲一個個相等大小的內存分區,回收時則以分區爲單位進- 行回收,存活的對象複製到另外一個空閒分區中。因爲都是以相等大小的分區爲單位進行操做,所以G1天- 然就是一種壓縮方案(局部壓縮);
  • G1雖然也是分代收集器,但整個內存分區不存在物理上的年輕代與老年代的區別,也不須要徹底獨立的- survivor(to space)堆作複製準備。G1只有邏輯上的分代概念,或者說每一個分區均可能隨G1的運行在不- 同代之間先後切換;
  • G1的收集都是STW的,但年輕代和老年代的收集界限比較模糊,採用了混合(mixed)收集的方式。即每次- 收集既可能只收集年輕代分區(年輕代收集),也可能在收集年輕代的同時,包含部分老年代分區(混合- 收集),這樣即便堆內存很大時,也能夠限制收集範圍,從而下降停頓

G1的內存模型

分區概念

以下圖所示:

分區

分區 Region

G1採用了分區(Region)的思路,將整個堆空間分紅若干個大小相等的內存區域,每次分配對象空間將逐段地使用內存。所以,在堆的使用上,G1並不要求對象的存儲必定是物理上連續的,只要邏輯上連續便可;每一個分區也不會肯定地爲某個代服務,能夠按需在年輕代和老年代之間切換。啓動時能夠經過參數-XX:G1HeapRegionSize=n可指定分區大小(1MB~32MB,且必須是2的冪),默認將整堆劃分爲2048個分區。

卡片

卡片 Card

在每一個分區內部又被分紅了若干個大小爲512 Byte卡片(Card),標識堆內存最小可用粒度全部分區的卡片將會記錄在全局卡片表(Global Card Table)中,分配的對象會佔用物理上連續的若干個卡片,當查找對分區內對象的引用時即可經過記錄卡片來查找該引用對象(見RSet)。每次對內存的回收,都是對指定分區的卡片進行處理。

堆 Heap

G1一樣能夠經過-Xms/-Xmx來指定堆空間大小。當發生年輕代收集或混合收集時,經過計算GC與應用的耗費時間比,自動調整堆空間大小。若是GC頻率過高,則經過增長堆尺寸,來減小GC頻率,相應地GC佔用的時間也隨之下降;目標參數-XX:GCTimeRatio即爲GC與應用的耗費時間比,G1默認爲9,而CMS默認爲99,由於CMS的設計原則是耗費在GC上的時間儘量的少。另外,當空間不足,如對象空間分配或轉移失敗時,G1會首先嚐試增長堆空間,若是擴容失敗,則發起擔保的Full GC。Full GC後,堆尺寸計算結果也會調整堆空間。

分代模型

分代

分代 Generation

分代垃圾收集能夠將關注點集中在最近被分配的對象上,而無需整堆掃描,避免長命對象的拷貝,同時獨立收集有助於下降響應時間。雖然分區使得內存分配再也不要求緊湊的內存空間,但G1依然使用了分代的思想。與其餘垃圾收集器相似,G1將內存在邏輯上劃分爲年輕代和老年代,其中年輕代又劃分爲Eden空間和Survivor空間。但年輕代空間並非固定不變的,當現有年輕代分區佔滿時,JVM會分配新的空閒分區加入到年輕代空間。

整個年輕代內存會在初始空間-XX:G1NewSizePercent(默認整堆5%)與最大空間-XX:G1MaxNewSizePercent(默認60%)之間動態變化,且由參數目標暫停時間-XX:MaxGCPauseMillis(默認200ms)、須要擴縮容的大小以及分區的已記憶集合(RSet)計算獲得。固然,G1依然能夠設置固定的年輕代大小(參數-XX:NewRatio、-Xmn),但同時暫停目標將失去意義。

結論

總的來講,G1能夠作到讓你本身來設置垃圾回收對系統的影響,他本身經過把內存拆分爲大量小Region,以及追蹤每一個Region中能夠回收的對象大小和預估時間,最後在垃圾回收的時候,儘可能把垃圾回收對系統形成的影響控制在你指定的範圍內,同時在有限的時間內儘可能回收可能多的垃圾對象

結尾

其實這個也就是一個簡單的的介紹,下面一篇咱們來講說線上環境G1垃圾回收器的具體使用和參數設置

由於博主也是一個開發萌新 我也是一邊學一邊寫 我有個目標就是一週 二到三篇 但願能堅持個一年吧 但願各位大佬多提意見,讓我多學習,一塊兒進步。

平常求贊

好了各位,以上就是這篇文章的所有內容了,能看到這裏的人呀,都是真粉

創做不易,各位的支持和承認,就是我創做的最大動力,咱們下篇文章見

六脈神劍 | 文 【原創】若是本篇博客有任何錯誤,請批評指教,不勝感激 !

相關文章
相關標籤/搜索