利用开源的LeakTracer项目可以打印出内存的调用栈,从而发现内存泄漏问题。

  • 首先下载LeakTracer的代码LeakTracer.zip,在这里为大家准备好了一份,见我的资源。
  • 然后将代码解压至AS的JNI目录下,即native代码的第一层。
  • 将LeakTracer的相关文件导入CMake

android native 内存泄漏查看 android native 内存泄露_perl


android native 内存泄漏查看 android native 内存泄露_内存泄漏_02


在代码块的开端添加头文件

android native 内存泄漏查看 android native 内存泄露_perl_03


并在主函数中的开头和结尾添加如下代码,即start和stop抓取的操作

android native 内存泄漏查看 android native 内存泄露_调用栈_04


android native 内存泄漏查看 android native 内存泄露_调用栈_05


这样就可以在指定目录得到一个文件,里面记录了所以未释放的内存调用信息,里面全都是地址信息,需要对so进行解析才能够看到调用

该文件是一个perl脚本,本地必须要有perl的环境,具体配置自行百度不加赘述。

配置完成后,利用LeakTracer自带的leak-analyze-addr2line工具进行解析so。注意请使用debug包,否则信息不一定完整,命令如下

perl xxx\LeakTracer\helpers\leak-analyze-addr2line xxx.so leaks.out

结果如下:

android native 内存泄漏查看 android native 内存泄露_perl_06

可以看到一共打印出了多少个leaks,并且每一处泄漏都会清晰的标明有多少内存泄漏以及调用栈。

上述调用栈打印的个数可以通过宏来控制

ALLOCATION_STACK_DEPTH

请注意这个值不要超过10,否则会出现奇怪的错误

但是并不是每一处都是真实的内存泄漏,会有误报的情况出现,也有可能是因为在停止监控时已经申请的内存还没有及时释放导致的,所以请务必仔细分析!

另外原生的LeakTracer代码并不能直接使用,需要改动几处,例如原生的代码的调用栈的使用问题在native上需要更换,或是打印出来的调用栈都是绝对地址需要转换成相对地址等等。