【C/C++】Jemalloc + Jeprof内存泄漏分析

70 篇文章 18 订阅

, 前提

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"

 

在VS Code上配置C/C++环境可以让你在Mac上进行C/C++开发。下面是配置步骤: 1. 安装VS Code:首先,你需要在Mac上安装VS Code。你可以从VS Code官方网站下载并安装最新版本的VS Code。 2. 安装C/C++扩展:打开VS Code,点击左侧的扩展图标(或按下快捷键Ctrl+Shift+X),在搜索框中输入"C/C++",找到并安装Microsoft的C/C++扩展。 3. 安装编译器:在Mac上,你可以使用GCC或Clang作为C/C++的编译器。如果你还没有安装编译器,可以通过以下步骤安装: - 安装Xcode:打开App Store,搜索并安装Xcode。安装完成后,打开Xcode,按照提示完成初始化设置。 - 安装命令行工具:打开终端(Terminal),运行以下命令安装命令行工具: ``` xcode-select --install ``` 4. 配置编译器路径:打开VS Code,点击左下角的齿轮图标,选择"Settings"。在搜索框中输入"C++",找到"C++: Compiler Path"选项,点击"Edit in settings.json",在打开的文件中添加以下内容: ``` "C_Cpp.default.compilerPath": "/usr/bin/gcc" ``` 5. 创建C/C++项目:在VS Code中,点击左侧的资源管理器图标(或按下快捷键Ctrl+Shift+E),选择一个文件夹作为你的项目目录。然后,点击左上角的"终端"菜单,选择"新建终端"。在终端中,你可以使用命令行工具来创建和编译C/C++项目。 以上就是在VS Code上配置C/C++环境的步骤。如果你按照以上步骤进行配置,你就可以在Mac上使用VS Code进行C/C++开发了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值