JAVA效能分析之使用火焰圖
隨著業務的發展,使用介面提供的服務的業務越來越多,不同的業務對呼叫耗時的要求不同,當然,耗時越少越好。而近來已經有三四個呼叫方反映介面呼叫耗時太不穩定,程式碼上的優化已經做了很多,有效果,但還不夠。同時,壓力測試顯示,複雜業務在呼叫量單機3000次/分時CPU就已經100%了,與預期差距太遠。為了改善介面效能,找到效能瓶頸,不得已祭出了大殺器————火焰圖。
網上的關於java火焰圖的講解大部分來自於Brendan Gregg的部落格,火焰圖的效果大致如下圖:
最終生成一個SVG格式的圖片,圖上的每個色塊代表的是一個執行緒棧幀,縱軸方向從下往上表示的是函式呼叫棧,而橫軸方向色塊的寬度表示的是函式呼叫佔用CPU的比例。在使用Profiler對CPU進行取樣時,根據CPU當前執行所處棧位置以及各個函式棧在總的取樣次數所佔比例就可以得出各個函式執行時的CPU佔用比例。
火焰圖生成方式
火焰圖的生成過程有兩步:
1. 使用Profiler工具生成trace檔案;
2. 將trace檔案轉換為svg格式的火焰圖檔案;
Brendan使用的Profiler是lightweight-java-profiler,這個需要自己編譯: make BITS=64 all
還可以通過更改global.h檔案來配置取樣次數:
// 每秒取樣次數
static const int kNumInterrupts = 100;
// Maximum number of stack traces
static const int kMaxStackTraces = 3000;
// 取樣棧深度
static const int kMaxFramesToCapture = 128;
在長時間取樣時,可以適當地減少每秒取樣次數,不然最終生成的檔案會很大,分析起來比較麻煩。
編譯生成檔案liblagent.so,使用起來很簡單,在java啟動引數新增如下內容: -agentpath:path/to/liblagent.so
java程式啟動後會在當前目錄生成一個traces.txt檔案,但檔案中只有一些說明資訊。程式正常結束(不是通過kill -9殺掉程式)後,才會寫入具體取樣資訊。
Brendan提供了一個工具集來將各種Profiler生成的檔案轉化為火焰圖svg格式。使用方式如下:
git clone http://github.com/brendangregg/FlameGraph
cd FlameGraph
./stackcollapse-ljp.awk < ../traces.txt | ./flamegraph.pl > ../traces.svg
除了使用lightweight-java-profiler作為Profiler外,還有其他的選擇,比如honest-profiler,lightweight-java-profiler會從java虛擬機器啟動開始取樣,而有時候我們需要在CPU飆高的時候開始,這時候honest-profiler提供的動態啟停功能就有用武之地了。
使用honest-profiler生成火焰圖:
首先,需要先下載或者手動編譯honest-profiler,使用方式如下:
java -agentpath:/path/to/location/liblagent.so=interval=7,logPath=/path/to/output/log.hpl,start=0,host=127.0.0.1,port=12345 <normal-java-commandline>
其中interval是取樣頻率,logPath表示生成的取樣檔案路徑,start可取0或1,表示是否啟動時就開啟取樣,host和port表示監聽控制的IP地址和埠號。
啟動成功後,通過telnet連線到127.0.0.1:12345,即可通過命令控制取樣的開始和結束。支援的命令包括:
- start,開始取樣
- stop,停止取樣
- status,列印當前取樣狀態和取樣檔案目錄
- get [ParamName],獲取引數值
- set [ParamName] [ParamValue1] ….[ParamValueN] 設定引數值
[ParamName]可以是intervalMin, intervalMax, interval, maxFrames 或者 logPath
在生成log.hpl檔案後,還需要通過其他工具才能轉換為log.svg檔案,當時是通過開源工具hprof2flamegraph執行的這個過程。使用步驟如下:
git clone https://github.com/chengxiayan/hprof2flamegraph.git
cd hprof2flamegraph
python stackcollapse_hpl.py --discard-lineno --discard-thread log.hpl>log.hpl.output
./flamegraph.pl log.hpl.output>log.svg
其中python版本需要2.7以上,windows上安裝了ActivePerl以後也可以通過執行
perl ./flamegraph.pl log.hpl.output>log.svg
來完成第二步轉換過程。
關於取樣工具的選取,可以看看文章 Evaluating the Accuracy of Java Profilers,這裡面列舉了xprof,hprof,jprofile和yourkit四種取樣器,並通過幾個壓測場景證明了這幾種取樣器的結果是相互矛盾的。總結的原因有三點:
1. 取樣器取樣點不夠隨機,這幾種取樣器都只有在safe point取樣;
2. 不同的取樣器會注入不同的程式碼,從而影響程式優化過程,同時也影響了safe point的分佈,進一步造成取樣差異;
honest-profiler號稱是避開了通過SUN/Oracle management agent去取樣堆疊,而是使用自己實現的使用UNIX 作業系統訊號和為Oracle Performance Studio 設計的內部API的sampling agent,從而提升了取樣準確率。
相關文章
- Flame Graph 火焰圖分析 Java 效能Java
- 使用火焰圖進行Java應用效能分析Java
- perf及火焰圖的使用,效能分析
- Linux程式效能分析和火焰圖Linux
- linux效能分析工具之火焰圖Linux
- openresty使用火焰圖排查效能問題REST
- Rust效能分析之測試及火焰圖,附(lru,lfu,arc)測試Rust
- Linux火焰圖效能分析文章及視訊演示Linux
- go效能調優之火焰圖Go
- 效能工具perf的用法以及如何繪製效能火焰圖
- Golang火焰圖Golang
- Chrome 火焰圖Chrome
- 在OR專案中使用火焰圖
- Golang FlameGraph(火焰圖)Golang
- 程式設計師精進之路:效能調優利器--火焰圖程式設計師
- 如何讀懂火焰圖?+ 例項講解程式效能優化優化
- linux 效能調優工具perf + 火焰圖 常用命令Linux
- perf/Simpleperf 生成火焰圖
- 容器化 RDS:藉助火焰圖定位Kubernetes效能問題
- 宋寶華:火焰圖 全域性視野的 Linux 效能剖析Linux
- Java 效能分析Java
- systemtap和火焰圖學習筆記筆記
- mongodb之使用explain和hint效能分析和優化MongoDBAI優化
- Linux效能分析流程圖Linux流程圖
- 效能分析之CPU分析-從CPU呼叫高到具體程式碼行(JAVA)Java
- Java 效能分析 5 大工具Java
- Linux下用perf生成火焰圖方法Linux
- perf 的資料用火焰圖顯示
- 溫故之.NET效能分析
- MySQL效能分析工具之PROFILEMySql
- Java之String和StringBuffer堆疊圖分析Java
- In和exists使用及效能分析(三):in和exists的效能分析
- Linux系統效能調優之效能分析Linux
- 使用CSS製作火焰燃燒動畫CSS動畫
- MySQL 查詢效能分析之 ExplainMySqlAI
- 008 Web Assembly之效能分析Web
- Android 效能分析工具之TraceViewAndroidView
- mysql效能分析之explain的用法MySqlAI