perf+火焰图使用

使用

# 安装perf
yum install perf -y
# 下载绘图工具
git clone https://github.com/brendangregg/FlameGraph.git

# 采集数据(perf record表示记录,-F99表示每秒99次,-p3887是进程号,即对哪个进程进行分析,-g表示记录调用栈,sleep 30则是持续30秒)
perf record -F99 -p3887 -g -- sleep 30

# 生成火焰图
perf script -i perf.data &> perf.unfold
./FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded
./FlameGraph/flamegraph.pl perf.folded > perf.svg

火焰图的含义

  1. 火焰图是基于 stack 信息生成的 SVG 图片, 用来展示 CPU 的调用栈。 y 轴表示调用栈, 每一层都是一个函数.
  2. 调用栈越深, 火焰就越高, 顶部就是正在执行的函数, 下方都是它的父函数. x 轴表示抽样数, 如果一个函数在 x 轴占据的宽度越宽,
  3. 就表示它被抽到的次数多, 即执行的时间长. 注意, x 轴不代表时间, 而是所有的调用栈合并后, 按字母顺序排列的.
  4. 火焰图就是看顶层的哪个函数占据的宽度最大. 只要有 “平顶”(plateaus), 就表示该函数可能存在性能问题。 颜色没有特殊含义,
  5. 因为火焰图表示的是 CPU 的繁忙程度, 所以一般选择暖色调.
    在这里插入图片描述

火焰图类型

常见的火焰图类型有 On-CPU,Off-CPU,还有 Memory,Hot/Cold,Differential 等等。它们有各自适合处理的场景。

火焰图类型 横轴含义 纵轴含义 解决问题 采样方式
on-cpu火焰图 cpu占用时间 调用栈 找出cpu占用搞的问题函数;分析代码热路径 固定频率采样cpu调用栈
off-cpu火焰图 阻塞时间 调用栈 i/o、网络等阻塞场景导致的性能下降;锁竞争、死锁导致的性能下降问题 固定频率采样阻塞事件调用栈
内存火焰图 内存申请/释放函数调用次数 调用栈 内存泄漏问题;内存占用高的对象/申请内存多的函数;虚拟内存或物理内存泄漏问题 有四种方式:跟踪malloc/free;跟踪brk;跟踪mmap;跟踪页错误
Hot/Cold火焰图 on-cpu和off-cpu综合展示 调用栈 需要结合cpu占用以及阻塞分析的场景;off-cpu火焰图无法直观判断的场景 on-cpu火焰图和off-cpu火焰图结合

On-CPU

如果是 CPU 则使用 On-CPU 火焰图

# 使用perf采集(perf record表示记录,-F99表示每秒99次,-p3887是进程号,即对哪个进程进行分析,-g表示记录调用栈,sleep 30则是持续30秒)
perf record -F 99 -p 34631 -g -- sleep 120 

# 生成火焰图
perf script | ./FlameGraph/stackcollapse-perf.pl | ./FlameGraph/flamegraph.pl > zeromq-req-rep.svg

Off-CPU

如果是 IO 或锁则使用 Off-CPU 火焰图.

# 使能sched_schedstats统计(root)
echo 1 > /proc/sys/kernel/sched_schedstats

# 使用perf采集
perf record -e sched:sched_stat_sleep -e sched:sched_switch -e sched:sched_process_exit -p 43777 -g -o perf.data.raw sleep 10 
perf inject -v -s -i perf.data.raw -o perf.data
# 通过perf分别记录sched:sched_stat_sleep、sched:sched_switch、sched:sched_process_exit三种事件,这三种事件分别表示:进程主动放弃 CPU 而进入睡眠的等待事件、进程由于I/O和锁等待等原因被调度器切换而进入睡眠的等待事件、进程的退出事件。

# 生成火焰图
perf script -F comm,pid,tid,cpu,time,period,event,ip,sym,dso,trace | awk '
    NF > 4 { exec = $1; period_ms = int($5 / 1000000) }
    NF > 1 && NF <= 4 && period_ms > 0 { print $2 }
    NF < 2 && period_ms > 0 { printf "%s\n%d\n\n", exec, period_ms }' | \
    ./FlameGraph/stackcollapse.pl | \
    ./FlameGraph/flamegraph.pl --countname=ms --title="Off-CPU Time Flame Graph" --colors=io > offcpu.svg
posted @ 2019-09-06 21:09  飞_2016  阅读(431)  评论(0编辑  收藏  举报