【perf工具和火焰图】

1 perf工具和火焰图简介

能做什么:

可以分析函数执⾏的频繁程度

可以分析哪些函数经常阻塞

可以分析哪些函数频繁分配内存

Flame Graph 原图路径:https://queue.acm.org/downloads/2016/Gregg4.svg
原图

2 通过perf收集函数堆栈信息绘制火焰图

2.1 安装perf

perf 命令(performance 的缩写)讲起, 它是 Linux 系统原⽣提供的性能分析⼯具, 会返回 CPU 正在执⾏的函数名以及调⽤栈(stack)

安装perf

 apt install linux-tools-common

测试perf是否可用 perf.data为产生的文件

┌──(root💀luo)-[~/workspace/flamegraph/src-flamegraph/test]
└─# perf record -F 99 -a -g -- sleep 10
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.598 MB perf.data (3370 samples) ]

┌──(root💀luo)-[~/workspace/flamegraph/src-flamegraph/test]
└─# ls
perf.data  perf.data.old  test  test.c

2.2 编译并运行测试程序

test.c 源码和接受在最下面

┌──(root💀luo)-[~/workspace/flamegraph/src-flamegraph/test]
└─# gcc -o test test.c -g
┌──(root💀luo)-[~/workspace/flamegraph/src-flamegraph/test]
└─# ./test 
main into

2.3 使用perf采集数据

perf record 表示采集系统事件, 没有使⽤ -e 指定采集事件, 则默认采集 cycles(即 CPU clock 周

期), -F 99 表示每秒 99 次, -p pidof test是进程号, 即对哪个进程进⾏分析, -g 表示记录调⽤栈,

sleep 30 则是持续 30 秒.

┌──(root💀luo)-[~/workspace/flamegraph/src-flamegraph/test]
└─# perf record -F 99 -p `pidof test` -g -- sleep 30 
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.235 MB perf.data (2962 samples) ]

┌──(root💀luo)-[~/workspace/flamegraph/src-flamegraph/test]
└─# ls
perf.data  perf.data.old  test  test.c

使用perf report 可以看到堆栈热点函数

┌──(root💀luo)-[~/workspace/flamegraph/src-flamegraph/test]
└─# perf report 

Samples: 2K of event 'cpu-clock:pppH', Event count (approx.): 29919191620             
  Children      Self  Command  Shared Object      Symbol                              
+  100.00%     0.00%  test     libc-2.31.so       [.] __libc_start_main
+  100.00%    29.71%  test     test               [.] main
+   35.58%    35.55%  test     test               [.] func_c
+   19.85%    19.85%  test     test               [.] func_b
+   14.85%     9.55%  test     test               [.] func_a
+    5.30%     5.30%  test     test               [.] func_d
     0.03%     0.03%  test     [kernel.kallsyms]  [k] __lock_text_start
     0.03%     0.00%  test     [kernel.kallsyms]  [k] apic_timer_interrupt
     0.03%     0.00%  test     [kernel.kallsyms]  [k] smp_apic_timer_interrupt
     0.03%     0.00%  test     [kernel.kallsyms]  [k] irq_exit
     0.03%     0.00%  test     [kernel.kallsyms]  [k] __softirqentry_text_start
     0.03%     0.00%  test     [kernel.kallsyms]  [k] run_timer_softirq
     0.03%     0.00%  test     [kernel.kallsyms]  [k] __run_timers.part.0
     0.03%     0.00%  test     [kernel.kallsyms]  [k] call_timer_fn
     0.03%     0.00%  test     [kernel.kallsyms]  [k] rh_timer_func
     0.03%     0.00%  test     [kernel.kallsyms]  [k] usb_hcd_poll_rh_status
     0.03%     0.00%  test     [kernel.kallsyms]  [k] uhci_hub_status_data

2.4 下载火焰图脚本

https://github.com/brendangregg/FlameGraph

git clone https://gitee.com/mirrors/FlameGraph.git

┌──(root💀luo)-[~/workspace/flamegraph/src-flamegraph/test]
└─# git clone https://gitee.com/mirrors/FlameGraph.git 
Cloning into 'FlameGraph'...
remote: Enumerating objects: 1147, done.
remote: Total 1147 (delta 0), reused 0 (delta 0), pack-reused 1147
Receiving objects: 100% (1147/1147), 1.87 MiB | 806.00 KiB/s, done.
Resolving deltas: 100% (674/674), done.

┌──(root💀luo)-[~/workspace/flamegraph/src-flamegraph/test]
└─# ls
FlameGraph  perf.data  perf.data.old  test  test.c

┌──(root💀luo)-[~/workspace/flamegraph/src-flamegraph/test]
└─# ls FlameGraph/
aix-perf.pl                      stackcollapse-gdb.pl
demos                            stackcollapse-go.pl
dev                              stackcollapse-instruments.pl
...
...

2.5 生成火焰图

┌──(root💀luo)-[~/workspace/flamegraph/src-flamegraph/test]
└─# perf script | ./FlameGraph/stackcollapse-perf.pl | ./FlameGraph/flamegraph.pl > process.svg

下载到windows桌面用浏览器打开查看效果

https://lzwtty.oss-cn-hangzhou.aliyuncs.com/blogimage/acknowledge/test_flamegraph.svg

test程序运行结果

可以很清晰的看到热点函数调用占用cpu使用率

2.5 ⽕焰图的含义

⽕焰图是基于 stack 信息⽣成的 SVG 图⽚, ⽤来展示 CPU 的调⽤栈。

  • y 轴表示调⽤栈, 每⼀层都是⼀个函数. 调⽤栈越深, ⽕焰就越⾼, 顶部就是正在执⾏的函数, 下

⽅都是它的⽗函数.

  • x 轴表示抽样数, 如果⼀个函数在 x 轴占据的宽度越宽, 就表示它被抽到的次数多, 即执⾏的时

间⻓. 注意, x 轴不代表时间, ⽽是所有的调⽤栈合并后, 按字⺟顺序排列的.

  • ⽕焰图就是看顶层的哪个函数占据的宽度最⼤. 只要有 “平顶”(plateaus), 就表示该函数可能存

在性能问题。

  • 颜⾊没有特殊含义, 因为⽕焰图表示的是 CPU 的繁忙程度, 所以⼀般选择暖⾊调.

源码test.c

#include <stdio.h>

void func_d() // 5
{
    for (int i = 5 * 10000; i--;); //5
}
void func_a()  // 10+5= 15
{
    for (int i = 10 * 10000; i--;); //10 
    func_d();   //5 
}
void func_b()
{
    for (int i = 20 * 10000; i--;);  // 20
}
void func_c()
{
    for (int i = 35 * 10000; i--;); // 35
}
int main(void)
{
    printf("main into\n");
    while (1)  // 100
    {
        for (int i = 30 * 10000; i--;); // 30 
        func_a(); //10+5 =15
        func_b(); // 20
        func_c(); // 35
    }
    printf("main end\n");
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值