博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android上使用leaktracer的经验分享
阅读量:4030 次
发布时间:2019-05-24

本文共 2169 字,大约阅读时间需要 7 分钟。

前言

上周使用了LeakTracer来分析我们项目的SDK的内存问题,最终的成效还算可以。工具能正常使用,通过内存泄漏日志文件中的函数调用堆栈,结合查看源代码找到不少的内存使用不当的问题。我的使用场景是:

  1. 在初始化SDK前调用 leaktracer::MemoryTrace::GetInstance().startMonitoringAllThreads(),启动内存监控。
  2. 在销毁SDK后再调用leaktracer::MemoryTrace::GetInstance().writeLeaksToFile("/sdcard/rt_leak.log") ,结束内存监控,并输出日志文件
  3. 通过日志文件case by case的分析问题

几条干货

跟大家分享下如几点

  • 官网的源码收集到的函数地址是进程地址空间的绝对地址,不利于后面的函数符号的解析,这里推荐使用这个哥们优化后的源码 ,主要优化点是,使用dladdr来做地址的转换(绝对地址换成so中的相对地址),有了相对地址,使用add2line工具还有有符号信息的so就能解析出具体的函数调用堆栈点的函数名,还有源文件的行号等信息了
  • 接入方式的话我是直接采用了源码的接入方式,把leaktracer源码放在我们SDK工程下跟SDK的源码一起编译并生成so,然后在AS的demo module去使用SDK的so 。有尝试过在demo module的jni层接入,即在demo 的cpp目录下放leaktracer的源码并构建,但始终收集到的日志解析出来的函数调用栈的符号解析不正常!(这个后期有时间需要研究下)
  • LeakTracer项目提供的日志文件的解析脚本 leak-analyze-addr2line(perl脚本) 中有使用到add2line命令行工具,所以需要我们的bash环境有add2line的配置,需要特别注意:通过alias配置add2line的路径,perl的运行环境是访问不到的。所以我的解决方案是修改leak-analyze-addr2line脚本,增加第三个参数,指定add2line的实际路径
    在这里插入图片描述
  • 建议还是直接使用addr2line一个case by case的去分析泄漏点的函数调用堆栈,可以考虑先分析内存泄漏比较严重中的case,于size的值为权重。
  • c++的类的虚构方法会自动的帮忙我们调用非指针类型的成员变量的虚构方法,帮忙我们回收成员变量的内存,但指针类型的成员变量是不会帮忙我们处理的。所以要特别关注指针类型的成员变量,一般内存泄漏多数是指针类型的成员变量引发。还有就是写代码的时候,特别要注意==nullptr与!=nullptr的判断,这种不小心的“低级”错误下,往往会伴随内存泄漏(判断条件写错了,没有调到delete 变量)。
  • 建议把leaktracer相关接口的调用再做一层封装,把接口的调用放到子线程中,这个在Android环境上更为重点与急切,避免ANR的出现
  • 需要处理申请应用读写文件的读取权限,否侧日志写入会失败!

PS: 本文对应的开发环境是 masOS Mojava 10.14.5

日志文件

日志文件的内容长如下样子

在这里插入图片描述
TIPS: 日志文件可以保存为cvs后缀,然后可以用WPS或osx上的Numbers表格打开,这样的话可以多维度或聚合性的去分析case,提高工作效率
在这里插入图片描述

add2line的使用

示例如下,这里使用addr2line工具解析数据调用堆栈,下面是使用llvm-addr2line的示例(macOS)

# llvm-addr2line is hashed (/Users/dw_luogongwu/Library/Android/sdk/ndk/21.2.6472646/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-addr2line)# llvm-addr2line -p -f -C -e so文件路径 函数地址(多个值,从leak.log的一行记录的stack值)

在这里插入图片描述

接入参考

如下是我们SDK的接入的情况,供大家参考

PS: 当前SDK是采用CMake来构建的

  1. 把leaktracer丢在工程cpp代码的根目录下
    在这里插入图片描述
    1.在CMakeLists.txt文件添加,leaktracer的编译配置
    加头文件
    在这里插入图片描述
    加cpp路径
    在这里插入图片描述

leaktracer的接入方式

引用自

可以以3种方式来使用使用LeakTracer:

  1. 将自己的程序与libleaktracer.a进行链接,也就是将自己的程序一个静态链接库libleaktracer.a进行链接,我们知道静态链接是会将库的代码揉进我们自己项目的目标代码so中的。
  2. 将自己的程序与libleaktracer.so进行链接。需要将-lleaktracer选项做为链接命令的第一个选项。当对程序执行"objdump -p"时,应该能看到leaktracer.so是Dynamic Section的第一个NEEDED entry才对。
  3. 通过LD_PRELOAD环境变量来使得libleaktracer.so在任何其它动态链接库之前被加载,然后不需要对程序做任何的更改,还可以通过环境变量来对LeakTracer的行为进行定制。

参考文档

转载地址:http://kumbi.baihongyu.com/

你可能感兴趣的文章
linux irqdebug
查看>>
git 常用命令
查看>>
linux位操作API
查看>>
snprintf 函数用法
查看>>
uboot.lds文件分析
查看>>
uboot start.s文件分析
查看>>
没有路由器的情况下,开发板,虚拟机Ubuntu,win10主机,三者也可以ping通
查看>>
本地服务方式搭建etcd集群
查看>>
安装k8s Master高可用集群
查看>>
忽略图片透明区域的事件(Flex)
查看>>
忽略图片透明区域的事件(Flex)
查看>>
AS3 Flex基础知识100条
查看>>
Flex动态获取flash资源库文件
查看>>
flex中设置Label标签文字的自动换行
查看>>
Flex 中的元数据标签
查看>>
flex4 中创建自定义弹出窗口
查看>>
01Java基础语法-11. 数据类型之间的转换
查看>>
01Java基础语法-13. if分支语句的灵活使用
查看>>
01Java基础语法-15.for循环结构
查看>>
01Java基础语法-16. while循环结构
查看>>