JAVA全面瞭解GC調優

有必要優化GC嗎?數組

確切的說是 基於Java的應用必定須要進行GC優化嗎?我認爲並不是全部基於Java的應用都須要進行GC優化,例如基於Java的系統有以下參數或行爲:性能

  • 已經經過-Xms 和 -Xmx 指定了內存大小
  • 包含了 -server 參數
  • 系統中未出現 超時 等日誌

換句話說,若是你沒有設置內存大小並且出現了大量超時日誌,那麼你須要在系統中進行GC優化了。 優化

可是有件事要銘記於心:GC優化是你最後的手段。ui

思考下GC優化的根本緣由:Java中建立的對象由垃圾收集器來清理,同時待清理對象的數量和各種GC的執行次數又和建立對象總數量成正比。所以,爲了控制GC的執行,首先要作的是 減小建立對象的總數量spa

俗話說,」聚沙成塔」。咱們須要關注一些小事情,不然」養成氣候」以後將難以駕馭。例如:日誌

  • 使用StringBuilder或StringBuffer代替String
  • 儘量少的輸出日誌

若是在幾回參數調整後內存使用狀況有所改善,你就能夠進行GC優化了。我將GC優化的目的分紅兩類:server

  • 將轉移到老年代的對象數量降到最少
  • 減小Full GC的執行時間(減小stop the word發生次數)

 

將轉移到老年代的對象數量降到最少

Oracle JVM提供了分代垃圾回收機制(JDK1.7及以上的G1 GC除外)。換句話說,對象建立在Eden區,而後在Survivor的From和To區之間移動,最後存活的對象被轉移到老年代。一些大對象在Eden區建立以後被直接轉移到老年代。相對新生代,老年代的GC消耗的時間更長。所以,減小重新生代轉移到老年代的對象數量能夠下降Full GC的頻率。對象

 減小重新生代轉移到老年代對象的數量的說法容易形成誤解,並且也不可能,但能夠經過 調全年輕代的大小 來實現。生命週期

減小Full GC的時間

和Minor GC相比,Full GC的執行時間長不少。所以,若是執行Full GC的時間過長(超過1s),將致使鏈接服務的請求超時。事件

若是經過減小老年代的大小來下降Full GC執行時間,會形成OutOfMemoryError或增長Full GC的次數

若是老年代設置太小,就會頻繁觸發full gc,full gc是很是耗時的。年輕代在通過n(hotspot默認是15)輪後會進入老年代,這樣老年代頂不住了,就會觸發full gc,回收時須要stop the world,這樣系統常常發生長時間停頓,影響系統的吞吐量。

若是增大老年代大小以期減小Full GC的執行次數,那麼執行時間又會增長

所以,須要合理的設置 老年代大小。

stop-the-world事件耗時很長

不合適的GC選項可能致使stop-the-world時間過長,你能夠經過分析器或heap dump來定位問題。

這意味着你能夠在檢查堆中對象類型和數量後判斷緣由。若是你發現不少沒必要要的對象,你最好修改源碼,若是建立對象過程當中沒有什麼特別的問題,最好直接變動GC參數。

影響GC性能的參數

不要去想 「有人在使用一些GC參數後性能顯著提高,爲何咱們不使用相同的參數?「,緣由是 不一樣Web應用中對象的大小和生命週期不一樣。

對於Java GC參數的設置,設置多個參數並不會提升GC的執行速度,偏偏相反,可能會下降執行速度。GC優化的基本原則是:將不一樣的GC參數應用到2個或多個主機,而後比對結果,最後將性能最優的參數組合推廣到其餘主機,這點必須銘記於心。

下表是一些影響GC性能的參數。

表1: GC優化時須要檢查的JVM參數

分類 參數 描述

堆區  -Xms 啓動JVM時的初始堆大小

         -Xmx 最大堆內存

新生代  -XX:NewRatio 新生代和老年代內存大小比例

             -XX:NewSize 新生代大小

             -XX:SurvivorRatio Eden和Survivor區的比率

 

我常用 -Xms、-Xmx、-XX:NewRatio 三個參數來進行GC調優。-Xms、-Xmx 是確定須要的,-XX:NewRatio 的設置將會顯著的影響GC性能。

有的人可能會問 如何設置Perm區大小? 你能夠經過 -XX:PermSize、-XX:MaxPermSize 設置,這個會與Perm區 OutOfMemoryError相關。

另外一個會影響GC性能的是 GC類型,下面是基於JDK1.6可選的GC類型:

類別   參數   備註

Serial GC                         -XX:+UseSerialGC

Parallel GC                      -XX:+UseParallelGC

                                        -XX:ParallelGCThreads=value

Parallel Compacting GC  -XX:+UseParallelOldGC

CMS GC                          -XX:+UseConcMarkSweepGC

                                        -XX:+UseParNewGC

                                        -XX:+CMSParallelRemarkEnabled

                                        -XX:CMSInitiatingOccupancyFraction=value

                                        -XX:+UseCMSInitiatingOccupancyOnly

G1                                   -XX:+UnlockExperimentalVMOptions

                                        -XX:+UseG1GC 在JDK6,這兩個參數必須同時使用

除G1 GC外,GC類型能夠經過第一行的參數來切換。最多見的GC類型是 Servial GC,它針對客戶端系統專門進行了優化。

影響GC性能的參數有不少,可是上面的參數有着最爲顯著的影響。記住,設置過多的參數並不能保證必定會縮短GC的時間。

參考:https://chenyongjun.vip/articles/56

相關文章
相關標籤/搜索