zl程序教程

您现在的位置是:首页 >  Javascript

当前栏目

使用jemalloc检测内存泄露

2023-04-18 14:23:26 时间

一、安装jemalloc

1.1、下载源码

wget https://github.com/jemalloc/jemalloc/archive/refs/tags/5.3.0.tar.gz

1.2、解压源码包

tar -zxv -f 5.3.0.tar.gz

1.3、编译并安装

cd jemalloc-5.3.0
./autogen.sh 在这个文件里面加上-configure后面-enable-prof参数
sudo make
sudo make install

由于要生成jeprof工具,所以要在autogen.sh文件中-configure后面-enable-prof参数

#!/bin/sh
#autogen.sh文件  
for i in autoconf; do
    echo "$i"
    $i
    if [ $? -ne 0 ]; then
        echo "Error $? in $i"
        exit 1
    fi
done

echo "./configure --enable-autogen $@"
./configure --enable-autogen --enable-prof $@ # 在这一行加
if [ $? -ne 0 ]; then
    echo "Error $? in ./configure"
    exit 1
fi

要在执行./autogen.sh之前加上

生成的jeprof工具在jemalloc-5.3.0/bin/文件夹中

二、程序启动准备

需要export两个环境变量,libjemalloc.so.2的绝对路径和jemalloc的参数

export LD_PRELOAD=“/usr/local/lib/libjemalloc.so.2”
export MALLOC_CONF=“prof_leak:true,lg_prof_sample:0,prof:true,prof_prefix:jeprof.out,prof_final:true,lg_prof_interval:30”

这里几个参数的含义分别为:

  • prof_leak:是否打开内存卸扣报告
  • lg_prof_sample:采样内存间隔,即每间隔分配多少内存启动一次采样
  • prof:这个参数在编译的时候就指定了
  • prof_prefix:采样文件名的前缀
  • prof_final:转储最终的内存使用情况
  • lg_prof_interval:每分配多少内存转储一次

更多参数的定义参见这里.

三、程序启动

会生成prof_prefix为前缀的heap文件,例如

jeprof.out.2381114.0.f.heap
jeprof.out.2381113.0.f.heap
jeprof.out.2381112.0.f.heap
jeprof.out.2380859.10.i10.heap
jeprof.out.2380859.11.i11.heap
jeprof.out.2380859.12.i12.heap
jeprof.out.2380859.13.i13.heap

3.1、生成svg

./jemalloc-5.3.0/bin/jeprof --show_bytes --svg ${服务二进制名} ${heap文件名} > out.svg

// 查看两个heap文件的diff
./jemalloc-5.3.0/bin/jeprof --show_bytes --svg 服务二进制名 − − b a s e = {服务二进制名} --base= 服务二进制名base={heap文件名} ${heap文件名} > diff.svg

如果生成svg时,报下面错误

/usr/bin/addr2line: DWARF error: could not find variable specification at offset 5fc4
/usr/bin/addr2line: DWARF error: could not find variable specification at offset 60c0
/usr/bin/addr2line: DWARF error: could not find variable specification at offset 6137

可以在编译的时候将-g换成-pg

生成的图,树上的每个节点代表一个函数,节点数据格式:

  • 函数名 或者 类名+方法名
  • 不包含内部函数调用的内存分配 (百分比)
  • of 包含内部函数调用的内存分配 (百分比) 如果没有内部调用函数则这一项数据不显示

一般程序不需要链接jemalloc源码,只用export LD_PRELOAD环境变量就行,如果有问题,可以将malloc改为jemalloc

cc_binary(
    name = "memory_leak",
    malloc = "@com_github_jemalloc//:jemalloc",
)