天天看點

硬核:JVM性能調優,有哪些好用的記憶體分析神器?

作者:老誠不bug

對于高并發通路量的電商、物聯網、金融、社交等系統來說,JVM記憶體優化是非常有必要的,可以提高系統的吞吐量和性能。通常調優的首選方式是減少FGC次數或者FGC時間,以避免系統過多地暫停。FGC達到理想值後,比如一天或者兩天觸發一次FGC。FCT時間優化為100~300毫秒後,再減少YoungGC次數或者YoungGC時間,YoungGC仍然會消耗CPU資源,優化YoungGC調用次數和消耗的CPU資源,可以提高系統的吞吐量。

優化GC前,必須擷取GC的實際使用情況,最好的方式是通過CG Log收集垃圾回收日志,通過一些可視化工具檢視垃圾回收分析資料,比如GCEasy。持續優化和對比優化前後的GC Log,能确認吞吐量和性能是否得到提升。

下面推薦幾個常用的記憶體分析指令和工具

jstat指令

JDK自帶的jstat指令用于檢視虛拟機垃圾回收的情況,如下指令使用gcutil參數輸出堆記憶體使用情況統計:

jstat –gcutil  -h 20 pid 1000 100
           

此指令顯示程序為pid的記憶體使用彙總,1000毫秒輸出一次,總共輸出100行。-h 20表示每20行輸出一次表頭。-gcutil表示顯示JVM記憶體使用彙總統計:

硬核:JVM性能調優,有哪些好用的記憶體分析神器?

清單顯示了虛拟機各個代的使用情況,描述了堆記憶體的使用占比和垃圾回收次數,以及占用時間,具體含義如下:

  • S0,第一個幸存區使用比值。
  • S1,第二個幸存區的使用率。
  • E,伊甸園區的使用比值。
  • O,老年代。
  • M,方法區、元空間使用率。
  • CCS,壓縮使用比值。
  • YGC,年輕代垃圾回收次數。
  • YGCT,年輕帶垃圾回收占用時間。
  • FGC,全局垃圾回收次數,這對性能影響至關重要。
  • FGCT,全局垃圾回收的消耗時間。
  • GCT,總的垃圾回收時間。

可以看到S0、S1、E變化頻率高,說明程式在頻繁建立生命周期短的對象,FGC為0,表示還未做過全局垃圾回收。如果FGC變化頻率很高,則說明系統性能和吞吐量将下降,或者可能出現記憶體溢出。

其他檢視彙總資訊的常用選項如下:

  • -gc,類似gcutil,gcutil以百分比形式顯示記憶體的使用情況,gc顯示的是記憶體占用的位元組數,以KB的形式輸出堆記憶體的使用情況。
  • -gccause,類似gcutil,額外輸出GC的原因。

jmap指令

jmap指令用于儲存虛拟機記憶體鏡像到檔案中,然後可以使用JVisualVM或者MAT工具進行進一步分析。指令如下:

jmap -dump:format=b,file=filename.hprof pid
           

需要注意,實際系統會有2GB到8GB記憶體,此指令會導緻虛拟機暫停工作1~3秒。還有一種是被動擷取方式,當虛拟機出現記憶體溢出的時候,會主動“dump”記憶體檔案。添加虛拟機啟動參數:

-XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=/tmp/heapdump.hprof
           

當虛拟機判斷達到記憶體溢出觸發條件的時候,會有如下輸出并儲存鏡像檔案:

java.lang.OutOfMemoryError: Java heap space
Dumping heap to heapdump.hprof ...
           

當獲得鏡像檔案後,打開JvisualVM工具,選擇菜單“File”,點選裝入,選擇我們儲存過的dump檔案,這時面闆會打開記憶體鏡像檔案。打開較大的記憶體鏡像檔案需要較長的時間,需要耐心等候,其他工具,如MAT,或者商業的YourKit Java Profiler打開鏡像檔案更快,分析功能更強大。

GCeasy

GCeasy是一個分析GC日志檔案的線上網站,能根據上傳的GC日志,以圖表形式顯示GC回收過程和統計資料。下圖顯示的是GC性能的統計情況,如吞吐量顯示為99.935%,說明隻有少量CPU資源用于垃圾回收。最長的GC時間是20毫秒,屬于正常範圍。在測試JVM參數調整是否能增加吞吐量,減小垃圾回收占用的CPU時,可以使用這個統計功能。

硬核:JVM性能調優,有哪些好用的記憶體分析神器?

下圖統計了GC總的時間和回收的位元組數,也顯示了Full GC的統計情況。

硬核:JVM性能調優,有哪些好用的記憶體分析神器?

JMC

Java Mission Control簡稱JMC,是JDK自帶的工具,是一個高性能的對象監視、管理、産生時間分析和診斷的工具套件,筆者主要用來追蹤熱點代碼與熱點線程,是主要的記憶體優化調優工具。

類似JVisualVM,通過JMX連接配接進入JMC控制台。

通過連接配接到遠端JVM程序後,可以執行飛行記錄(FlightRecord),選擇飛行記錄存放的路徑與執行時間即可,如下圖所示。需要注意的是,執行飛行記錄功能時會對目前JVM程序有一定的性能影響(大約為5%~10%),是以建議JMC連接配接隔離環境中的伺服器并執行飛行記錄功能。

硬核:JVM性能調優,有哪些好用的記憶體分析神器?

通過一段時間的記錄,飛行記錄可以反映線程的繁忙程度,以及CPU的熱點方法。

使用熱點方法可以直接找到最耗時的幾個方法,對熱點方法重點優化就可以使CPU的使用率下降一大截。

飛行記錄還可以反映記憶體增長的熱點方法,以及顯示機關時間内建立的最多對象的方法。下圖為找到的記憶體對象中建立的最多的char[]的方法,一個是Fastjson,另一個是Kryo。

硬核:JVM性能調優,有哪些好用的記憶體分析神器?

小結:通過JMC的熱點方法的統計結果可以有針對性地進行優化,筆者通過對線上系統進行優化使得CPU使用率下降了40%、記憶體GC頻率下降了100%以上。

MAT

MAT是Memory Analyzer的簡稱,它是一款功能強大的Java堆記憶體分析器,可以分析具有數億個對象的記憶體鏡像,快速計算對象大小,自動找到嫌疑的洩漏對象并形成記憶體洩漏報告。MAT是基于Eclipse開發的,是一款免費的記憶體鏡像分析工具,是筆者發現記憶體洩漏原因的主要工具。

通過File-Open Heap Dump可以打開記憶體鏡像檔案,顯示内容如下圖所示。

硬核:JVM性能調優,有哪些好用的記憶體分析神器?

它提供了Leak Suspects 報告,輸出有可能發生記憶體洩漏的對象。

OQL

OQL語句類似SQL語句,可以在VisualVM、MAT等大多數記憶體鏡像分析工具中執行,完成對象查找任務。

來源:https://mp.weixin.qq.com/s/mC02prjMO0aNvG5lgLpQMA

繼續閱讀