本文记录下日常工作中用到的性能分析工具。
一、内存泄漏排查
我的服务依赖了 jemalloc,这个地方记录下使用 jemalloc 进行内存分析的方法。
1 编译 jemalloc
首先,依赖的 jemalloc lib 需要开启 profiling 功能。
$ wget https://github.com/jemalloc/jemalloc/archive/5.2.1.tar.gz
$ tar xvf 5.2.1.tar.gz
$ cd jemalloc-5.2.1/
$ mkdir build; cd build
$ ../autogen.sh
$ ../configure --prefix=/path/to/build --enable-prof
$ make -j8
2 编译应用程序
3 设置 jemalloc 环境变量
在执行应用程序之前,需要设置好用于 jemalloc heap profiling 的环境变量。
$ export MALLOC_CONF=prof_leak:true,lg_prof_sample:19,prof:true,prof_prefix:jeprof.out,prof_final:true,lg_prof_interval:29
prof: bool类型,表示是否开启profiling。开启后,将会剖析程序的内存申请操作。而且只有开启,下面的参数才会生效。 官方文档:http://jemalloc.net/jemalloc.3.html#opt.prof
prof_leak: bool类型,是否开启profiling memory leak,默认是false,即disabled。开启后,将会在调用atexit(3)函数时生成memory leak报告。也就是程序结束时产出报告,但是一般服务型程序是不会主动退出的,如果使用kill将进程退出是不起作用的,所以对于服务型守护进程,使用lg_prof_interval间隔性产出内存剖析报告。 官方文档:http://jemalloc.net/jemalloc.3.html#opt.prof_leak
lg_prof_sample: size_t类型,分配样本之间的平均间隔,以分配活动的字节数衡量。增加采样间隔会降低配置文件的保真度,但也会降低计算开销。默认值是19,即默认的采样间隔是512 KiB (2^19 B)。这个参数不能设置太小,如果设置为0表明内存申请的采样精度是1字节,profiling机制也需要占用内存,设置为0程序可能很快就会OOM,而且极大影响程序性能。
上例中19表示采样精度是2^19 = 512KB
官方文档: http://jemalloc.net/jemalloc.3.html#opt.lg_prof_sample
prof_prefix: 产出heap剖析报告文件的前缀。注意可以是路径,比如 /tmp/jeprof.out
官方文档: http://jemalloc.net/jemalloc.3.html#opt.prof_prefix
prof_final: bool类型。
官方文档: http://jemalloc.net/jemalloc.3.html#opt.prof_final
lg_prof_interval: 内存剖析文件dump的平均间隔,以分配活动的字节数衡量。剖析文件落盘的文件名格式:
上例中29表示大约每隔申请2^29=512MB的内存时,dump一次剖析文件。
官方文档: http://jemalloc.net/jemalloc.3.html#opt.lg_prof_interval
4 运行应用程序
5 产生报告
运行应用程序后,会在本地生成一些 heap profile 文件。在第一步编译 jemalloc 时,产出了一个 jeprof 工具,用来生成报告。
首先安装绘图工具依赖:
yum install graphviz
yum install ghostscript
第二步 将 heap 文件转换为 pdf 格式:
$ jeprof --show_bytes 应用程序 -pdf jeprof.out.9579.0.i0.heap > 0.pdf
或者比较两次dump的差异
$ jeprof --show_bytes 应用程序 -pdf --base jeprof.out.9579.0.i0.heap jeprof.out.8429.1.i1.heap > 0.pdf
二、cpu 分析
基于 linux perf dump 程序数据,并生成火焰图查看。
1 找到要分析的进程 id
2 使用 perf 收集信息
perf record -a -g -F99 -p 进程id sleep 60
3 生成火焰图
使用 perf script 将 perf.data 转为可读数据
perf script > perf.script
使用 FlameGraph 生成火焰图
./FlameGraph/stackcollapse-perf.pl perf.script | ./FlameGraph/flamegraph.pl > report.svg
三、函数性能分析
使用 perf top 可以查看某个进程的耗时百分比分布,从而知道哪些函数比较耗时:
server_name="xsearch_leaf_kdweibocrawler"
pid=`pidof $server_name`
echo $pid
perf top -p $pid
打印函数调用链的性能占比
perf record -F 99 -p ${pid} --call-graph dwarf sleep ${采样时间}
执行perf report
可以看到各个子函数性能占比。