STW(stop-the-world):當GC觸發時爲了正常且高效的執行,大部分狀況下,會要求系統進入一個停頓的狀態(終止全部的應用線程),保證應用再也不產生新的垃圾及在某一瞬間的一致性,也更好的標記對象。因此這時應用程序將沒有任何的響應,這個停頓叫STW。合理的配置堆與選擇GC是優化的關鍵。 java
新生代GC------------------------------------------------------------- 算法
1.串行回收器
單線程,獨佔式。單線程進行垃圾回收,每次回收只有一個線程在工做。它是最古老的一種當,jvm在client模式下它是默認的GC,由於古董因此成熟,它使用複製算法,實現相對簡單、邏輯處理特別高效、且沒有線程切換的開銷。因此在單核cpu是不錯的選擇,特色:
①僅僅使用單線程
②獨佔式的(回收過程當中,應用程序所有暫停直到回收結束) 多線程
-XX:+UseSerialGC //新生代與老年代都使用串行回收器
併發
2.ParNew
多線程,獨佔式。在多核cpu狀況下停頓時間要短於串行GC,但在單核狀況下可能還不如串行GC jvm
--XX:+UseParNewGc //新生代使用ParNew; 老年代使用串行GC
--XX:+UseConcMarkSweepGC //新生代使用ParNew; 老年代使用CMS
--XX:ParallelGcThreads //ParNew 使用的線程數量
參數說明:通常與cpu數量至關,當cpu數量大於8個時個數=3+((5*cpu個數)/8) 性能
3.ParallelGC
多線程,獨佔式。與ParNew不一樣的是它很是關注系統的吞吐量(垃圾回收時間越少吞吐量就越高) 優化
-XX:+UserParallelGc //新生代使用ParalleGC; 老年代使用串行GC
-XX:+UserParallelOldGC //新生代使用ParalleGC; 老年代使用ParalleOldGC
-XX:MaxGCPauseMillis //垃圾回收停頓時間,一個大於0的整數
參數說明:jvm會盡量的把停頓時間調整到你所設的值之間,若是值很小勢必致使回收次數增多,下降了吞 吐量
-XX:GCTimeRatio //吞吐最的大小;一個0~100的整數,默認19
參數說明:如取值99,則系統用於垃圾收集時間不超過1/(1+99)=1%,若是值很大那麼停頓時間就會變長。
-XX:+UseAdaptiveSizePolicy //自動調整新生代空間大小,eden/survivor比例、晉升老年代的年齡參 數等,達到堆大小、吞吐量和停頓時間之間的平衡點。而你只要設置
MaxGcPauseMillis與GCTimeRatio就行 spa
老年代GC--------------------------------------------------- 線程
1.串行回收器
單線程,獨佔式。與新生代中差很少,使用標記壓縮算法。老年代的GC使用時間比新生代都要來行久(由於空間比較大,且算法的原故),因此在老年代串行GC它的停頓會久,它能夠與不少新生代GC一塊兒配置使用,也能夠做爲CMS 的的備用GC。 對象
-XX:+UseSerialGC //新生代與老年代都使用串行回收器
-XX:+UseParNewGC //新生代使用ParNew ; 老年代使用串行
-XX:+UseParallelGc //新生代使用ParallelGC ; 老年代使用串行
2ParallelOld
多線程,獨佔式。它也是關注吞吐量的,與新生代中ParallelGC配合使用
-XX:+UseParallelOldGC //新生代使用ParallelGC; 老年代使用ParalleOld
-XX:ParallelGCThreads //設置垃圾回收時線程數量
3.CMS(Concurrent Mark Sweep 併發標記清除)
多線程,非獨佔。與ParallelOld不一樣,它關注的是系統停頓時間,使用標記清除算法。非獨佔是從總體來講的,由於在回收階段中還有一些是獨佔的,不能徹底作到非獨佔。這樣雖然CMS的非獨佔減小了停頓時間,但在cpu緊張時受到CMS線程的影響。應用系統的性能可能很是的糟糕。
由於非獨佔,CMS在回收過程當中系統同時也會產生出新的垃圾。雙重做用下系統內存會很緊張,因此CMS不會等到內存不足時纔去工做,而是在老年代空間達到必定值(CMSInitiatingOccupancyFraction)時就去加收。若是回收過程當中已經出現了內存不足了,此時CMS就會失敗,轉而使用備用GC(即老年代串行回收器)。這時應用程序徹底中斷直到GC結束,這樣反而情形更壞了,因此設置CMSInitiatingOccupancyFraction變得很重要
-XX:+UseConcMarkSweepGC //新生代使用ParNew; 老年代使用CMS
-XX:ConcGCThread 或 -XX:ParallelCMSThreads //併發線程數量
參數說明:默認數量是(ParallelGCThreads+3)/4。
-XX:CMSInitiatingOccupancyFraction68 //指當老年代空間使用率達68%時執行一次CMS,默認68
-XX:+UseCMSCompactAtFullCollection //指當CMS後進行一次內存碎片整理
-XX:CMSFullGCsBeforeCompaction5 //指通過5次CMS後進行一次內存碎片整理
-XX:+CMSClassUnloadingEnabled //容許CMS回收Perm區的Class數據
-XX:CMSInitiatingPermOccupancyFraction60 //當永久區使用率達到60%時,Perm就進行回收
雙工GC----------------------------------------------------------------------
1.G1(Garbage-First)
多線程,非獨佔。這個是在jdk1.7中正式使用的全新垃圾回收器,目標爲了取代CMS。與以前的回收器大相徑庭由於它增長了分區算法,這樣從結構上看它並不要求整個eden、年輕代、老年代都連續。但G1依然屬於分代回收器,只是在邏輯上劃分了。如上圖
特色(主要於CMS進行比對):
①並行性:GC回收過程當中多個線程同時工做
②併發性:G1部分工做與應用程序交替工做
③雙工: 它同時兼顧年輕代與老年代。與上面的不一樣,它們或者工做在年輕代或者工做在老年代
④內存整理:在回收過程就進行對象的移動,不像CMS要特別進行一次碎片清理
⑤分區: 由於採用了分區,因此G1能夠只選取部分區域進行回收,控制了一次回收內存大小。減小了停頓
與CMS同樣當內存空間不足,jvm就會放棄G1轉而使用Full GC,一樣會出現應用程序的停頓。
-XX:+UseG1GC //使用G1回收器
-XX:MaxGCPauseMillis //指定目標最大停頓時間
參數說明:若是GC任何一次停頓超過這個值,G1就會嘗試調整新生代和老年代的比例、調整堆的大小、調整晉升年齡,試圖達到預設目標。若是該值偏小,對於新生代意味着增長GC的次數。對於老年代來講增長了Full GC的可能。
-XX:ParallelGCThreads //並行回收,GC的工做線程數量
-XX:InitiatingHeapOccupancyPercent45 //指定當整個堆使用率達到45%時執行併發標記
參數說明:一旦該值設定,始終都不會被G1修改,這意味着G1不會試圖改變這個值,來知足MaxGCPauseMillis的目標,該值偏大會致使併發週期遲遲行不到啓動,引發Full GC;若是該值偏小,會使得併發週期變得頻繁,產生大量的GC線程最終將致使應用程序性能降低。
擴展點---------------------------------------------------------------------------
Full GC
這個並非一個特別的垃圾回收器,指老年代的回收而應用程序將徹底中斷。同時串行與並行的Full GC是不同,區別在於並行的FullGC 在回收老年代的同時,也會觸發新生代的回收,而串行不會。若是不須要這個特性可使用如下參數
-XX:-ScavengeFeforeFullGC //除去full gc 以前的那次新生代GC
System.gc()
在java中咱們能夠調用System.gc()去觸發一次Full GC。而通常狀況下咱們認爲回收動做是交給系統的,無需手動去觸發,頻繁觸發對系統性能很差。並且使用System.gc(),在默認狀況下是獨佔cpu(不管你是否使用併發GC),也就是說應用程序將中斷運行,因此不建議使用。
-XX:+DisableExplicitGC //java 中禁用System.gc(),即便調用也視爲一個空方法
-XX:+ExplicitGCInvokesConcurrent //調用System.gc()後讓GC併發去回收垃圾
知識點--------------------------------------------
併發線程
併發也就是非獨佔的,指GC線程與應用線程進行交替執行
並行線程 一種任務下多個線程同時執行。如並行GC,指多個線程同時執行GC這個任務