重要參考文獻:html
www.brendangregg.com/blog/2017-06-30/package-flame-graph.htmljava
www.brendangregg.com/blog/2014-06-12/java-flame-graphs.htmllinux
Java FlameGraph(火焰圖)可以很是直觀的展現java程序的性能分析結果,方便發現程序熱點和進一步調優。本文將展現如何使用linux perf工具生成java程序的火焰圖。火焰圖大體長這個樣子:git
http://www.brendangregg.com/blog/images/2014/cpu-vertx-flamegraph.svggithub
火焰圖的橫軸表示方法耗時百分比,某個方法佔用橫軸越長表示佔用的CPU越多,縱軸表示函數調用關係,頂端表示調用的棧頂。jvm
linux perf是一款linux下強大的性能分析工具。學習請參考:svg
https://www.ibm.com/developerworks/cn/linux/l-cn-perf1/index.html函數
http://www.brendangregg.com/perf.html工具
使用perf工具生成java程序的火焰圖只需兩步操做,體如今以下命令當中:性能
# sudo perf record -F 99 -a -- sleep 30; ./jmaps # sudo perf script | ./pkgsplit-perf.pl | grep java | ./flamegraph.pl > out.svg
第一步使用perf record收集程序運行時的堆棧信息;
第二部使用perf script生成分析結果,最終生成的out.svg文件就是火焰圖。
上述命令中還用到了jmaps、pkgsplit-perf.pl、flamegraph.pl等腳本,這些腳本分類來自git項目https://github.com/brendangregg/FlameGraph。其中要着重說明的是jmaps腳本,該腳本的做用是獲取java程序運行時的符號表,這樣在執行perf script時才能生成有意義的堆棧信息,該腳本依賴git項目 https://github.com/jvm-profiling-tools/perf-map-agent,下載該項目成功編譯後會在out目錄下生成attach-main.jar和libperfmap.so兩個文件,這是獲取java程序運行時符號表的關鍵。打開jmaps文件,能夠看到以下代碼:
AGENT_HOME=${AGENT_HOME:-/usr/lib/jvm/perf-map-agent} # from https://github.com/jvm-profiling-tools/perf-map-agent
須要手動將AGENT_HOME替換爲剛纔編譯後的per-map-agent/out/目錄。
問題彙總:
perf-map-agent編譯失敗
perf-map-agent編譯須要cmake和JDK,請現安裝好cmake和JDK,並配置好JAVA_HOME。
執行./jmaps腳本出錯,ERROR: not root user? exiting...
這是由於當前用戶不是root, 直接註釋掉jmaps腳本中的以下代碼便可:
if [[ "$USER" != root ]]; then
echo "ERROR: not root user? exiting..."
exit
fi
執行./jmaps腳本出錯,chown: changing ownership of '/tmp/perf-xxx.map': Operation not permitted
將jmaps中的代碼
if [[ -e "$mapfile" ]]; then
chown root $mapfile
chmod 666 $mapfile
else
改成:
if [[ -e "$mapfile" ]]; then
sudo chown root $mapfile
sudo chmod 666 $mapfile
else
jmaps只能獲取正在執行的java程序的符號表
使用jmaps獲取java程序的符號表,僅限於正在運行的Java程序,一種狀況是perf record時要監測的java程序還在運行,但等到執jmaps腳本時程序已經結束,則符號表獲取會失敗。