java-GC調優

一.目的
    GC 的時間夠小
    GC 的次數夠少
    發生 Full GC 的週期足夠的長,時間合理,最好是不發生。
二.調優的原則和步驟
    1. 大多數的 java 應用不須要 GC 調優
    2. 大部分須要 GC 調優的的,不是參數問題,是代碼問題
    3. 在實際使用中,分析 GC 狀況優化代碼比優化 GC 參數要多得多;
    4. GC 調優是最後的手段
三.GC調優的最重要的三個選項:
    第一位:選擇合適的 GC 回收器
    第二位:選擇合適的堆大小
    第三位:選擇年輕代在堆中的比重
四.步驟
    1:監控 GC的狀態使用各類 JVM 工具,查看當前日誌,分析當前 JVM 參數設置,而且分析當前堆內存快照和 gc 日誌,根據實際的各區域內存劃分和 GC 執行時間,以爲是否進行優化;
    2:分析結果,判斷是否須要優化若是各項參數設置合理,系統沒有超時日誌出現,GC 頻率不高,GC 耗時不高,那麼沒有必要進行 GC 優化;若是 GC 時間超過 1-3 秒,或者頻繁 GC,則必須優化;
        注: 若是知足下面的指標,則通常不須要進行 GC :
                Minor GC 執行時間不到 50ms;
                Minor GC 執行不頻繁,約 10 秒一次;
                Full GC  執行時間不到 1s ;
                Full GC 執行頻率不算頻繁,不低於 10 分鐘 1 次;
    3:調整GC類型和內存分配若是內存分配過大或太小,或者採用的 GC 收集器比較慢,則應該優先調整這些參數,而且先找1臺或幾臺機器進行beta,而後比較優化過的機器和沒有優化的機器的性能對比,並有針對性的作出最後選擇;
    4:不斷的分析和調整經過不斷的試驗和試錯,分析並找到最合適的參數
    5:全面應用參數若是找到了最合適的參數,則將這些參數應用到全部服務器,並進行後續跟蹤。
五.學會閱讀GC日誌
以參數-Xms5m -Xmx5m -XX:+PrintGCDetails -XX:+UseSerialGC 爲例:
[DefNew: 1855K->1855K(1856K), 0.0000148 secs][Tenured: 2815K->4095K(4096K),0.0134819 secs] 4671K
DefNew 指明瞭收集器類型,並且說明了收集發生在新生代。1855K->1855K(1856K)表示,回收前 新生代佔用 1855K,回收後佔用 1855K,新生代大小 1856K。0.0000148 secs 代表新生代回收耗時。Tenured 代表收集發生在老年代2815K->4095K(4096K),0.0134819 secs:含義同新生代最後的 4671K 指明堆的大小。
收集器參數變爲-XX:+UseParNewGC,日誌變爲:
[ParNew: 1856K->1856K(1856K), 0.0000107 secs][Tenured: 2890K->4095K(4096K),0.0121148 secs]
收集器參數變爲-XX:+ UseParallelGC 或 UseParallelOldGC,
日誌變爲:
[PSYoungGen: 1024K->1022K(1536K)] [ParOldGen: 3783K->3782K(4096K)]4807K->4804K(5632K),
CMS 收集器和 G1 收集器會有明顯的相關字樣
六.其餘與GC相關的參數
    調試跟蹤之打印簡單的GC信息參數: -verbose:gc, -XX:+PrintGC
    打印詳細的GC信息 -XX:+PrintGCDetails, +XX:+PrintGCTimeStamps
    -Xlogger:logpath設置gc的日誌路,如: -Xlogger:log/gc.log, 將 gc.log 的路徑設置到當前目錄的 log 目錄下.    應用場景: 將 gc 的日誌獨立寫入日誌文件,將 GC 日誌與系統業務日誌進行了分離,方便開發人員進行追蹤分析。
    -XX:+PrintHeapAtGC, 打印推信息參數設置: 
    -XX:+PrintHeapAtGC   應用場景:獲取 Heap 在每次垃圾回收先後的使用情況
    -XX:+TraceClassLoading參數方法: 
    -XX:+TraceClassLoading應用場景,在系統控制檯信息中看到class加載的過程和具體的class信息,可用以分析類的加載順序以及是否可進行精簡操做。
    -XX:+DisableExplicitGC 禁止在運行期顯式地調用 System.gc()
    -XX:-HeapDumpOnOutOfMemoryError 默認關閉,建議開啓,在java.lang.OutOfMemoryError 異常出現時,輸出一個 dump.core 文件,記錄當時的堆內存快照。
    -XX:HeapDumpPath=./java_pid<pid>.hprof 默認是 java 進程啓動位置,用來設置堆內存快照的存儲文件路徑。
七.推薦策略-年輕代大小選擇
· 響應時間優先的應用:儘量設大,直到接近系統的最低響應時間限制(根據實際狀況選擇).在此種狀況下,年輕代收集發生的頻率也是最小的.同時,減小到達年老代的對象.· 吞吐量優先的應用:儘量的設置大,可能到達 Gbit的程度.由於對響應時間沒有要求,垃圾收集能夠並行進行,通常適合 8CPU 以上的應用.· 避免設置太小.當新生代設置太小時會致使:1.YGC 次數更加頻繁 2.可能致使 YGC 對象直接進入舊生代,若是此時舊生代滿了,會觸發 FGC.年老代大小選擇0.響應時間優先的應用:年老代使用併發收集器,因此其大小須要當心設置,通常要考慮併發會話率和會話持續時間等一些參數.若是堆設置小了,能夠會形成內存碎 片,高回收頻率以及應用暫停而使用傳統的標記清除方式;若是堆大了,則須要較長的收集時間.最優化的方案,通常須要參考如下數據得到:併發垃圾收集信息、持久代併發收集次數、傳統 GC 信息、花在年輕代和年老代回收上的時間比例。吞吐量優先的應用:通常吞吐量優先的應用都有一個很大的年輕代和一個較小的年老代.緣由是,這樣能夠儘量回收掉大部分短時間對象,減小中期的對象,而年老代盡存放長期存活對象java

相關文章
相關標籤/搜索