java实例_图例 | Java混合模式分析之火焰图实例
這是小小的第五篇
前言
在進(jìn)行性能調(diào)優(yōu)的時(shí)候,通常會(huì)借助性能分析工具,常用的性能分析工具有perf,DTrace,分析系統(tǒng)資源的使用情況,這些情況根據(jù)CPU,內(nèi)存,生成相關(guān)的文本數(shù)據(jù),這些文本數(shù)據(jù)不容易直接理解,所以采用火焰圖進(jìn)行分析。用圖表的形式展示出來。本文將會(huì)展示具體實(shí)例。
火焰圖
火焰圖有不同的資源和事件類型,包括的主要數(shù)據(jù)有 CPU,Memory,Off-CPU,Hot/Cold。等等。下文中,所描述的火焰圖指的是CPU的火焰圖。
小方塊 每個(gè)小方塊代表一個(gè)函數(shù),對(duì)應(yīng)一個(gè)棧幀,小方塊的寬度表示該函數(shù)在采樣期間出現(xiàn)的頻率,寬度越寬表示出現(xiàn)的頻率越高。
棧幀 用于記錄函數(shù)的活動(dòng)記錄,保存函數(shù)局部變量,函數(shù)參數(shù)等信息。因此想要分析函數(shù)調(diào)用堆棧關(guān)系,這里就需要使用采樣得到棧幀信息。
Y 表示函數(shù)的調(diào)用棧,體現(xiàn)了stack深度,每個(gè)垂直方向的頂端小方塊表示正在使用CPU的棧的深度。
X ?表示采用數(shù)據(jù)的總量,X表示數(shù)據(jù)在對(duì)調(diào)用進(jìn)行合并之后的結(jié)果。根據(jù)函數(shù)的字母順序進(jìn)行排列。X不代表使用CPU的長(zhǎng)短,只是說明該方法出現(xiàn)的次數(shù),寬度越寬表示該方法出現(xiàn)的次數(shù)越多。X可以直接作為CPU的時(shí)間長(zhǎng)短。
生成火焰圖
采樣數(shù)據(jù) -> 使用腳本生成 圖解如下
工具
火焰圖是根據(jù)任何包含stack traces 的 profile 數(shù)據(jù)生成,需要采集stack traces 數(shù)據(jù), 列舉如下的工具,采集相關(guān)的數(shù)據(jù)
Linux perf_events Mac DTrace and Instruments windows Xperf.exe
這里采用的是perf,在Linux系統(tǒng)下實(shí)驗(yàn)
安裝
sudo yum install perf生成數(shù)據(jù)
sudo perf record -F 99 -a -g -- sleep 30此時(shí)會(huì)在當(dāng)前目錄下生成perf.data文件。
生成火焰圖
sudo perf script | ./stackcollapse-perf.pl | ./flamegraph.pl > out.svg會(huì)自動(dòng)在當(dāng)前目錄下查找perf.data文件,然后生成svg文件。
然后會(huì)自動(dòng)生成相對(duì)應(yīng)的火焰圖
Java混合模式火焰圖
安裝 perf
perf --version安裝perf-map-agent
安裝gcc和gcc-c++
sudo yum install gccsudo yum install gcc-c++
安裝cmake
sudo mkdir /home/q/perf-toolscd /home/q/perf-tools/cmake-2.8.6
sudo ./configure --prefix=/home/q/cmake-2.8.6
sudo make && make install
安裝perf-map-agent
git clone https://github.com/jvm-profiling-tools/perf-map-agentcd /home/q/perf-tools/perf-map-agent
sudo /home/q/cmake-2.8.6/bin/cmake . && sudo make
配置Java選項(xiàng)
JDK >= Java 8 update 60 build 19參數(shù) **-XX:+PreserveFramePointer**
檢查Jdk
java -version
檢查JVM
ps wwp `pgrep -n java`|grep PreserveFramePointer --color
設(shè)置 -XX:+PreserveFramePointer
-Xms24g -Xmx24g -server -XX:+DisableExplicitGC -Dqunar.logs=$CATALINA_BASE/logs -Dqunar.cache=$CATALINA_BASE/cache -verbose:gc -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGC -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=1 -Xloggc:$CATALINA_BASE/logs/gc.log -XX:+PrintSafepointStatistics -XX:ReservedCodeCacheSize=512m -XX:CMSInitiatingOccupancyFraction=50 -XX:+UseCMSInitiatingOccupancyOnly -XX:MaxTenuringThreshold=14 -XX:+PreserveFramePointer
安裝FlameGraph
git clone https://github.com/brendangregg/FlameGraph.git生成腳本
sudo ./gen-flame-graph.sh $SLEEP_SECONDS $PID具體腳本內(nèi)容
#!/bin/bashSLEEP_SECONDS=$1
PID=$2
PERF_TOOLS_HOME=$(pwd)
GEN_RESULTS_DIR=$PERF_TOOLS_HOME/gen-flame-graphs-result
AGENT_HOME=$PERF_TOOLS_HOME/perf-map-agent
AGENT_JAR=$AGENT_HOME/attach-main.jar
AGENT_OUT=$AGENT_HOME/out
FLAME_GRAPH_PL_HOME=$PERF_TOOLS_HOME/FlameGraph
FLAME_GRAPH_GENERAGED_FILE=$PERF_TOOLS_HOME/flamegraph-mixed-model-`date +%Y%m%d-%H%M%S`.svg
MAP_FILE=/tmp/perf-$PID.map
function check_env(){
if [[ ! -x $JAVA_HOME ]]; then
echo "ERROR: JAVA_HOME not set correctly; edit $0 and fix"
exit
fi
if [[ ! -x $AGENT_HOME ]]; then
echo $AGENT_HOME
echo "ERROR: AGENT_HOME not set correctly; edit $0 and fix."
exit
fi
if [[ ! -x $GEN_RESULTS_DIR ]]; then
echo "ERROR: '$GEN_RESULTS_DIR' not found;Please mkdir a file :'$GEN_RESULTS_DIR'"
exit
fi
}
#generate perf.data with command: perf record
function perf_record(){
echo "Perf record for all processors with sleep 30 seconds."
cmd_perf="sudo perf record -F 99 -a -g -- sleep 30"
eval $cmd_perf
if [[ -e "./perf.data" ]]; then
echo "SUCCESS: perf.data was generated."
else
echo "ERROR: perf.data not generated;edit $0 and fix."
exit
fi
}
#agent mapping pid
function gen_map_file(){
user=$(ps ho user -p $PID)
echo "Agent mapping PID $PID with user $user"
cmd_agent="cd $AGENT_HOME;java -cp attach-main.jar:$JAVA_HOME/lib/tools.jar net.virtualvoid.perf.AttachOnce $PID"
cmd_agent="sudo -u $user sh -c '$cmd_agent'"
eval $cmd_agent
if [[ -e "$MAP_FILE" ]]; then
echo "generate map file"
chown root $MAP_FILE
chmod 666 $MAP_FILE
else
echo "ERROR: $MAP_FILE not created."
exit
fi
}
#generate flame graph
function gen_flame_graph(){
cmd_stack="sudo perf script|$FLAME_GRAPH_PL_HOME/stackcollapse-perf.pl --pid|$FLAME_GRAPH_PL_HOME/flamegraph.pl --color=java --width=800 --minwidth=0.5 -- --hash > $FLAME_GRAPH_GENERAGED_FILE"
eval $cmd_stack
}
check_env
perf_record
gen_map_file
gen_flame_graph
echo "SUCCESS: generate flame graph."
使用腳本
改腳本是對(duì)Java進(jìn)程的8708采樣30s,生成flamegraph-mixed-model-date +%Y%m%d-%H%M%S.svg的Java混合模式火焰圖
sudo ./gen-flame-graph.sh 30 8708生成的圖片
小明菜市場(chǎng)
推薦閱讀●?理論 | 教你徹底學(xué)會(huì)Java序列化和反序列化
●?面試 | 從一個(gè)API緩存演化,詳細(xì)了解Redis各項(xiàng)功能
●?理論 | 六種延遲隊(duì)列的實(shí)現(xiàn)方案
●?實(shí)戰(zhàn) | Element UI 父子組件傳值與事件綁定(逆向)
●?實(shí)戰(zhàn) | Element UI 父子組件傳值與事件綁定(正向)
? ? ? ? ? ? ??? ? ? ??
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的java实例_图例 | Java混合模式分析之火焰图实例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hashmap原理_想要彻底搞懂Hash
- 下一篇: gitee markdown 笔记_使用