一, 前提
1 jemalloc lib 需要开启 profiling 功能
既编译 jemalloc的时候添加--enable-prof 选项 (同时会生成一个jeprof 工具,用来生成报告)
$ 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 设置 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: 是否开启profiling,true开启. 开启后,将会剖析程序的内存申请操作。而且只有开启,下面的参数才会生效。 官方文档: http://jemalloc.net/jemalloc.3.html#opt.prof
- prof_leak:是否开启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的平均间隔,以分配活动的字节数衡量。剖析文件落盘的文件名格式:...i.heap,其中是由opt.prof_prefix选项控制。默认情况下,区间触发的配置文件转储被禁用(编码为-1)
上例中29表示大约每隔申请2^29=512MB的内存时,dump一次剖析文件。
官方文档: http://jemalloc.net/jemalloc.3.html#opt.lg_prof_interval
二,运行应用程序
运行应用程序后,会在本地生成一些 heap profile 文件。
图形分析
首先安装绘图工具依赖:
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
命令行分析
(原文:https://docs.tibco.com/pub/activematrix_businessworks/6.6.1/doc/html/GUID-231E1EFC-EA7C-4072-B0F4-0D92093D3161.html)
(jeprof 是在第一步编译 jemalloc 时生成的 jeprof 工具,用来生成报告。该jeprof工具在jemalloc/bin文件夹。执行jeprof,jeprof控制台打开。)
执行命令直接进入控制台分析文件:
jeprof --show_bytes <PATH to 可执行文件> jeprof.*.heap #同时查看多个文件
jeprof --show_bytes <PATH to 可执行文件> <Heap file name> #查看单个文件
键入 top 当您到达 jeprof 控制台时。例如:
jeprof --show_bytes /usr/lib/jvm/java-8-oracle/jre/bin/java jeprof*.heap
Using local file /usr/bin/w.
Using local file jeprof.19678.0.f.heap.
Welcome to jeprof! For help, type 'help'.
(jeprof) top
它显示以下输出:
Total: 267184 B
258032 96.6% 96.6% 258032 96.6% _3_2_5
3616 1.4% 97.9% 3616 1.4% _nl_intern_locale_data
2048 0.8% 98.7% 2208 0.8% __tzfile_read
1024 0.4% 99.1% 1024 0.4% getpwnam
1024 0.4% 99.5% 1072 0.4% getpwuid
448 0.2% 99.6% 448 0.2% __gconv_lookup_cache
224 0.1% 99.9% 224 0.1% strdup
160 0.1% 99.9% 160 0.1% __tzstring
128 0.0% 100.0% 3760 1.4% _nl_load_locale_from_archive
48 0.0% 100.0% 48 0.0% get_mapping
要在分析完成并识别出泄漏嫌疑人后停止分析,请运行命令:
unset MALLOC_CONF
如果未停止性能分析,则会持续生成 jeprof 堆文件。
三、cpu 分析
基于 linux perf dump 程序数据,并生成火焰图查看。
1 找到要分析的进程 id
2 使用 perf 收集信息
perf record -a -g -F99 -p 进程idsleep60
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可以看到各个子函数性能占比。
基于原文:c++ 性能分析 - 我的娃会叫爸爸啦 - 博客园 (cnblogs.com)
简略:
1, 编译安装 jemalloc时, configure 参数设置 --enable-prof
2,运行程序程序运行时链接 jemalloc 库
2.程序退出时的内存分配状态
MALLOC_CONF=prof_leak:true,lg_prof_sample:0,prof_final:true
LD_PRELOAD=libjemalloc.so.2 ./a.out
输出内存泄漏统计信息
<jemalloc>: Leak approximation summary: ~5120 bytes, ~2 objects, >= 2 contexts
<jemalloc>: Run jeprof on dump output for leak detail
hello world
jeprof 分析泄漏调用栈
jeprof a.out jeprof.64551.0.f.heap
top 命令,web 输出图形或者生成堆栈图
jeprof --show_bytes --pdf a.out jeprof.64551.0.f.heap > a.pdf
3. 程序运行时采样获取 Heap Profiling (3)
上述方法获取的时机是程序运行终止时得到的,也可以设置程序运行时采样获取
MALLOC_CONF="prof:true,lg_prof_interval:20"
LD_PRELOAD=libjemalloc.so.2 ./a.out
lg_prof_interval 采样周期,表示每积攒申请 1M 大小的内存就dump一次 (生成一个heap分析文件)
--base 指定对比基线heap文件,生成增量
设置达到新高时做一次 dump
export MALLOC_CONF="prof:true,prof_gdump:true"
在代码里手动dump
需要include jemalloc的头文件并链接jemalloc库: gcc -I/usr/local/jemalloc-5.1.0/include main.c -L/usr/local/jemalloc-5.1.0/lib -ljemalloc
mallctl api
然后设置conf export MALLOC_CONF="prof:true,prof_prefix:jeprof.out" 并运行
在 run_tikv.sh 中做如下修改, 设置 256M dump 一次内存
export MALLOC_CONF="prof:true,prof_prefix:jeprof.out,lg_prof_interval:28,prof_final:true"
设置 512M dump 一次内存
export MALLOC_CONF="prof:true,prof_prefix:jeprof.out,lg_prof_interval:29,prof_final:true"