因爲有些年輕代和老年代回收器沒法兼容,通常使用都是用如下四個組合。java
java -XX:+PrintCommandLineFlags -version
算法
Serial做爲年輕代回收器和Serial Old垃圾回收器(JDK1.3版本以前)做爲老年代回收器。在JDK1.3版本以前是惟一選擇,如今基本不用,由於是單進程收集器,沒有發揮出如今多核並行處理的優點。併發
ParNew做爲年輕代回收器,CMS做爲老年代回收器,通常須要手動指定,由於如今jdk7,8默認不是使用這個策略。而是使用的下面的Parallel Scavenge + Parallel Old。其基本收集原理和下面的Parallel Scavenge + Parallel Old沒有區別,區別在於Parallel Scavenge和 Parallel Old有自適應調節策略,直接能夠適應最大吞吐量。但忽略了停頓時間,不適用於要求用戶體驗的場景,個別請求可能等待時間較長。而ParNew + CMS主要場景是注重控制單次回收停頓時間。性能
JDK6版本以後引入,Parallel Scavenge做爲年輕代回收器,Parallel Old做爲老年代回收器,在JDK6以前,Parallel Scavenge只能適配Serial Old,如今是JDK7,JDK8的默認組合。特色上面說了就是適應最大吞吐量。線程
G1回收器,JDK7出現,JDK9以後的默認回收器,老年代和年輕代均可以回收,特色是直接對停頓時間進行設置。code
上一篇就介紹了垃圾回收機制,可是沒有針對各個回收器進行區別,實際上上一篇文章就是基於ParNew + CMS來介紹的,其餘垃圾回收器包括Serial + Serial Old,Parallel Scavenge + Parallel Old基本上是相同的機制。只不過Serial + Serial Old是單線程回收,全程阻塞用戶線程,Scavenge + Parallel Old更注重吞吐量,自適應調節,不須要手動指定新生代的大小,Eden和Survivor區的比例,晉升老年代對象等細節參數。但G1會稍稍有點不同。對象
這裏主要分兩塊來說,分別以ParNew + CMS和G1回收器來介紹下其中在第二篇文章沒有提到的細節以及G1與其的區別。blog
parNew的回收機制跟上篇文章介紹的相同,採起復制算法清理。parNew的特色是並行進行垃圾回收,充分利用現代處理器的多核優點。值得注意的是並行並非和用戶線程並行,在垃圾回收階段仍是會阻塞用戶線程。另外能夠利用上面的-XX:ParallelGCThreads
參數指定並行線程數量,不指定的話ParNewGC會自動根據CPU核數適配。進程
回收分爲四個階段:內存
最後根據-XX:+UseCMSCompactAtFullCollection
和-XX:CMSFullGCsBeforeCompactio
參數,選擇進行碎片整理,碎片整理的時候會阻塞用戶線程。
存在的問題:
我的以爲由於老年代預測存活對象會比年輕代多,若是用複製算法可能涉及到存活的對象會不少,意味着suprivor區也必須預留不少空間,這顯然是不合適的。
1.併發標記階段,存活對象多,須要追蹤對象(樹越深,越長)多,而MinorGC須要追蹤的對象少,速度很快
2.併發清理階段不是清理連續的內存空間,清理速度也慢。
3.碎片整理,對象也多,也慢。
最核心的參數配置是-XX:MaxGCPauseMills
,G1回收器會根據用戶設置的停頓時間(最大容許阻塞用戶線程的時間)以及每一個region的回收成本(G1會維護每一個region能夠回收的對象大小和回收預估時間),選擇性價比最高的region(回收對象大,回收預估時間小)來進行回收,儘可能在垃圾回收停頓時間內回收儘量多的垃圾。
G1回收器不管是老年代和年輕代都是用複製清理算法。
針對大對象由單獨的region進行存放,不在進入老年代。
進入老年代的條件跟之前同樣,如達到必定年齡、動態年齡判斷規則、清理後的存活對象suprivor區放不下都會轉移到老年代。
根據-XX:G1MaxNewSizePercent
設置的新生代最大佔比(默認60%),達到的時候觸發minorGC。
G1回收器沒有單獨的oldGC,而是mixGC,其會回收老年代加年輕代以及大對象。其觸發條件是根據-XX:InitiatingHeapOccupancyPercent
參數指定的(默認45%),表示老年代對象達到45%的region觸發mixedGC。
-XX:G1MixedGCCountTarget
參數控制,默認分8次進行回收),接下來就是阻塞用戶線程,選擇部分region全力開始垃圾回收,G1會控制停頓時間在指定的範圍內。注:
-XX:G1HeapWastePercent
(默認5%)能夠指定空閒Region爲多少的時候中止混合回收。當達到的時候混合回收終止。-XX:G1MixedGCLiveThresholdPercent
能夠指定當一個region裏面的存活對象必須低於多少才能回收這個region(默認85%),表示必須是存活對象低於85%的region才能夠回收,爲何會有這個參數緣由在於存活對象大的region採用複製算法成本過高,移動成本以及空閒空間成本。相比CMS+ParNew,二者都強調下降停頓時間,但G1更適合大內存機器,CMS+ParNew釋放內存比較簡單直接,會比G1更完全,佔用CPU也會更小。簡單來講大內存機器用G1,通常內存大小的機器建議用CMS+ParNew