文本已收錄至個人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
到JDK1.8爲止的垃圾回收器圖以下web
其實他們的一個迭代的過程是隨着技術的演化進行的算法
開啓選項:-XX:+SerialGC安全
串行收集器是最基本、發展時間最長、久經考驗的垃圾收集器,也是client模式下的默認收集器配置。服務器
串行收集器採用單線程stop-the-world的方式進行收集。當內存不足時,串行GC設置停頓標識,待全部線程都進入安全點(Safepoint)時,應用線程暫停,串行GC開始工做,採用單線程方式回收空間並整理內存。單線程也意味着複雜度更低、佔用內存更少,但同時也意味着不能有效利用多核優點。事實上,串行收集器特別適合堆內存不高、單核甚至雙核CPU的場合。多線程
開啓選項:-XX:+UseParallelGC或-XX:+UseParallelOldGC(可互相激活)併發
並行收集器是以關注吞吐量爲目標的垃圾收集器,也是server模式下的默認收集器配置,對吞吐量的關注主要體如今年輕代Parallel Scavenge收集器上。編輯器
並行收集器與串行收集器工做模式類似,都是stop-the-world方式,只是暫停時並行地進行垃圾收集。年輕代採用複製算法,老年代採用標記-整理,在回收的同時還會對內存進行壓縮。關注吞吐量主要指年輕代的Parallel Scavenge收集器,經過兩個目標參數-XX:MaxGCPauseMills和-XX:GCTimeRatio,調整新生代空間大小,來下降GC觸發的頻率。並行收集器適合對吞吐量要求遠遠高於延遲要求的場景,而且在知足最差延時的狀況下,並行收集器將提供最佳的吞吐量。學習
開啓選項:-XX:+UseConcMarkSweepGC
併發標記清除(CMS)是以關注延遲爲目標、十分優秀的垃圾回收算法,開啓後,年輕代使用STW式的並行收集,老年代回收採用CMS進行垃圾回收,對延遲的關注也主要體如今老年代CMS上。
年輕代ParNew與並行收集器相似,而老年代CMS每一個收集週期都要經歷:初始標記、併發標記、從新標記、併發清除。其中,初始標記以STW的方式標記全部的根對象;併發標記則同應用線程一塊兒並行,標記出根對象的可達路徑;在進行垃圾回收前,CMS再以一個STW進行從新標記,標記那些由mutator線程(指引發數據變化的線程,即應用線程)修改而可能錯過的可達對象;最後獲得的不可達對象將在併發清除階段進行回收。值得注意的是,初始標記和從新標記都已優化爲多線程執行。CMS很是適合堆內存大、CPU核數多的服務器端應用,也是G1出現以前大型應用的首選收集器。
可是CMS並不完美,它有如下缺點:
開啓選項:-XX:+UseG1GC
以前介紹的幾組垃圾收集器組合,都有幾個共同點:
G1垃圾收集器也是以關注延遲爲目標、服務器端應用的垃圾收集器,被HotSpot團隊寄予取代CMS的使命,也是一個很是具備調優潛力的垃圾收集器。雖然G1也有相似CMS的收集動做:初始標記、併發標記、從新標記、清除、轉移回收,而且也以一個串行收集器作擔保機制,但單純地以相似前三種的過程描述顯得並非很穩當。事實上,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垃圾回收器的具體使用和參數設置
由於博主也是一個開發萌新 我也是一邊學一邊寫 我有個目標就是一週 二到三篇 但願能堅持個一年吧 但願各位大佬多提意見,讓我多學習,一塊兒進步。
好了各位,以上就是這篇文章的所有內容了,能看到這裏的人呀,都是真粉。
創做不易,各位的支持和承認,就是我創做的最大動力,咱們下篇文章見
六脈神劍 | 文 【原創】若是本篇博客有任何錯誤,請批評指教,不勝感激 !