天天看點

JVM性能調優的6大步驟,及關鍵調優參數詳解JVM性能調優方法和步驟JVM調優參數參考

JVM性能調優的6大步驟,及關鍵調優參數詳解

  • JVM性能調優方法和步驟
    • 1.監控GC的狀态
    • 2.生成堆的dump檔案
    • 3.分析dump檔案
    • 4.分析結果,判斷是否需要優化
    • 5.調整GC類型和記憶體配置設定
    • 6.不斷分析和調整
  • JVM調優參數參考

對JVM記憶體的系統級的調優主要的目的是減少GC的頻率和Full GC的次數。

1.Full GC

會對整個堆進行整理,包括Young、Tenured和Perm。Full GC因為需要對整個堆進行回收,是以比較慢,是以應該盡可能減少Full GC的次數。

2.導緻Full GC的原因

  • 年老代(Tenured)被寫滿

    調優時盡量讓對象在新生代GC時被回收、讓對象在新生代多存活一段時間和不要建立過大的對象及數組避免直接在年老代建立對象 。

  • 持久代Pemanet Generation空間不足

    增大Perm Gen空間,避免太多靜态對象 ,控制好新生代和年老代的比例

  • System.gc()被顯示調用

    垃圾回收不要手動觸發,盡量依靠JVM自身的機制

    在對JVM調優的過程中,很大一部分工作就是對于FullGC的調節,下面詳細介紹對應JVM調優的方法和步驟。

JVM性能調優方法和步驟

1.監控GC的狀态

使用各種JVM工具,檢視目前日志,分析目前JVM參數設定,并且分析目前堆記憶體快照和gc日志,根據實際的各區域記憶體劃分和GC執行時間,覺得是否進行優化。

舉一個例子: 系統崩潰前的一些現象:

  • 每次垃圾回收的時間越來越長,由之前的10ms延長到50ms左右,FullGC的時間也有之前的0.5s延長到4、5s
  • FullGC的次數越來越多,最頻繁時隔不到1分鐘就進行一次FullGC
  • 年老代的記憶體越來越大并且每次FullGC後年老代沒有記憶體被釋放
  • 之後系統會無法響應新的請求,逐漸到達OutOfMemoryError的臨界值,這個時候就需要分析JVM記憶體快照dump。

2.生成堆的dump檔案

通過JMX的MBean生成目前的堆(Heap)資訊,大小為一個3G(整個堆的大小)的hprof檔案,如果沒有啟動JMX可以通過Java的jmap指令來生成該檔案。

3.分析dump檔案

打開這個3G的堆資訊檔案,顯然一般的Window系統沒有這麼大的記憶體,必須借助高配置的Linux,幾種工具打開該檔案: Visual VM

、IBM HeapAnalyzer、JDK 自帶的Hprof工具、Mat(Eclipse專門的靜态記憶體分析工具)推薦使用。

   注:檔案太大,建議使用Eclipse專門的靜态記憶體分析工具Mat打開分析。

4.分析結果,判斷是否需要優化

如果各項參數設定合理,系統沒有逾時日志出現,GC頻率不高,GC耗時不高,那麼沒有必要進行GC優化,如果GC時間超過1-3秒,或者頻繁GC,則必須優化。

   注:如果滿足下面的名額,則一般不需要進行GC:

  • Minor GC執行時間不到50ms;
  • Minor GC執行不頻繁,約10秒一次;
  • Full GC執行時間不到1s;
  • Full GC執行頻率不算頻繁,不低于10分鐘1次;

5.調整GC類型和記憶體配置設定

如果記憶體配置設定過大或過小,或者采用的GC收集器比較慢,則應該優先調整這些參數,并且先找1台或幾台機器進行beta,然後比較優化過的機器和沒有優化的機器的性能對比,并有針對性的做出最後選擇。

6.不斷分析和調整

通過不斷的試驗和試錯,分析并找到最合适的參數,如果找到了最合适的參數,則将這些參數應用到所有伺服器。

JVM性能調優的6大步驟,及關鍵調優參數詳解JVM性能調優方法和步驟JVM調優參數參考

JVM調優參數參考

  1. 針對JVM堆的設定,一般可以通過-Xms -Xmx限定其最小、最大值,為了防止垃圾收集器在最小、最大之間收縮堆而産生額外的時間,通常把最大、最小設定為相同的值;
  2. 年輕代和年老代将根據預設的比例(1:2)配置設定堆記憶體, 可以通過調整二者之間的比率NewRadio來調整二者之間的大小,也可以針對回收代。比如年輕代,通過 -XX:newSize -XX:MaxNewSize來設定其絕對大小。同樣,為了防止年輕代的堆收縮,我們通常會把-XX:newSize -XX:MaxNewSize設定為同樣大小。
  3. 年輕代和年老代設定多大才算合理
  • 更大的年輕代必然導緻更小的年老代,大的年輕代會延長普通GC的周期,但會增加每次GC的耗時;小的年老代會導緻更頻繁的Full GC
  • 更小的年輕代必然導緻更大年老代,小的年輕代會導緻普通GC很頻繁,但每次的GC時間會更短;大的年老代會減少Full GC的頻率

       如何選擇應該依賴應用程式對象生命周期的分布情況: 如果應用存在大量的臨時對象,應該選擇更大的年輕代;如果存在相對較多的持久對象,年老代應該适當增大。但很多應用都沒有這樣明顯的特性。

       在抉擇時應該根據以下兩點:

       (1)本着Full GC盡量少的原則,讓年老代盡量緩存常用對象,JVM的預設比例1:2也是這個道理 。

    (2)通過觀察應用一段時間,看其他在峰值時年老代會占多少記憶體,在不影響Full GC的前提下,根據實際情況加大年輕代,比如可以把比例控制在1:1。但應該給年老代至少預留1/3的增長空間。

  1. 在配置較好的機器上(比如多核、大記憶體),可以為年老代選擇并行收集算法: -XX:+UseParallelOldGC 。
  2. 線程堆棧的設定:每個線程預設會開啟1M的堆棧,用于存放棧幀、調用參數、局部變量等,對大多數應用而言這個預設值太了,一般256K就足用。

       理論上,在記憶體不變的情況下,減少每個線程的堆棧,可以産生更多的線程,但這實際上還受限于作業系統。

繼續閱讀