jvm診斷與優化(6)

    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這個任務

相關文章
相關標籤/搜索