准备环境
下载jemalloc下载链接
因为是native的,所以我们要在自己用的机器上进行编译。我使用的是ubuntu系统。
编译时有很多编译选项,可以参考项目的wiki里。wiki
我们只需要加内存检测的功能就好,所以只加一个参数。
./configure --enable-prof
make && make install
编译成功后,我们可以看到库位置的输出
/usr/bin/install -c -d /usr/local/bin
/usr/bin/install -c -m 755 bin/jemalloc-config /usr/local/bin
/usr/bin/install -c -m 755 bin/jemalloc.sh /usr/local/bin
/usr/bin/install -c -m 755 bin/jeprof /usr/local/bin
/usr/bin/install -c -d /usr/local/include/jemalloc
/usr/bin/install -c -m 644 include/jemalloc/jemalloc.h /usr/local/include/jemalloc
/usr/bin/install -c -d /usr/local/lib
/usr/bin/install -c -m 755 lib/libjemalloc.so.2 /usr/local/lib
ln -sf libjemalloc.so.2 /usr/local/lib/libjemalloc.so
/usr/bin/install -c -d /usr/local/lib
/usr/bin/install -c -m 755 lib/libjemalloc.a /usr/local/lib
/usr/bin/install -c -m 755 lib/libjemalloc_pic.a /usr/local/lib
/usr/bin/install -c -d /usr/local/lib/pkgconfig
/usr/bin/install -c -m 644 jemalloc.pc /usr/local/lib/pkgconfig
Missing xsltproc. doc/jemalloc.html not (re)built.
Missing xsltproc. doc/jemalloc.3 not (re)built.
/usr/bin/install -c -d /usr/local/share/doc/jemalloc
/usr/bin/install -c -m 644 doc/jemalloc.html /usr/local/share/doc/jemalloc
/usr/bin/install -c -d /usr/local/share/man/man3
/usr/bin/install -c -m 644 doc/jemalloc.3 /usr/local/share/man/man3
这里的目录可以记录一下,知道我们需要的库要从哪里查找。
准备测试用例
下面是一个申请直接内存的例子
import java.nio.ByteBuffer;
public class Malloc {
public static void main(String[] args) {
new Thread(()->{
int i=0;
while (i<10){
ByteBuffer buffer = ByteBuffer.allocateDirect(1024*1024*10);
i++;
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
添加环境变量
export MALLOC_CONF="prof_leak:true,lg_prof_sample:0,prof_final:true"
export LD_PRELOAD="/usr/local/lib/libjemalloc.so"
lg_prof_sample后的数字是2的n次的意思,这里需要根据自己的阈值进行设置。
这里设置的是最后输出结果,如果是需要按照大小输出,需要更改配置。
export MALLOC_CONF="prof:true,lg_prof_interval:4"
这里多大生成一个文件需要自己设置。
java Malloc
我们可以看到这样的输出字样
<jemalloc>: Leak approximation summary: ~83261344 bytes, ~3275 objects, >= 1120 contexts
<jemalloc>: Run jeprof on "jeprof.17013.0.f.heap" for leak detail
查看分析结果
jeprof /usr/bin/java jeprof.17013.0.f.heap
可以用top命令查看最大
(jeprof) top
Total: 179.4 MB
131.0 73.0% 73.0% 131.0 73.0% je_prof_backtrace
48.0 26.8% 99.8% 79.0 44.0% SUNWprivate_1.1
0.4 0.2% 100.0% 0.4 0.2% Java_java_util_zip_ZipFile_getZipMessage
0.0 0.0% 100.0% 0.0 0.0% _dl_new_object
0.0 0.0% 100.0% 0.0 0.0% allocate_dtv
0.0 0.0% 100.0% 0.0 0.0% _dl_check_map_versions
0.0 0.0% 100.0% 0.4 0.2% ZIP_Unlock
0.0 0.0% 100.0% 0.0 0.0% Java_java_util_zip_Inflater_init
0.0 0.0% 100.0% 48.0 26.8% _dlerror_run
0.0 0.0% 100.0% 0.0 0.0% 0x0000000000400620
生成调用路径
安装依赖
sudo apt-get install ghostscript graphviz
生成命令
jeprof --show_bytes --pdf /usr/bin/java jeprof.17013.0.f.heap > my.pdf
适用范围
jemalloc针对java的场景一般是对系统内存的分析,堆内的对象可以做heapdump,直接内存的这种,是java程序自己保证了内存的回收的。只有例如jni这样的是容易出现问题,所以场景更多针对于系统内存的检测。