概述
Android Native内存泄漏诊断
1、基础诊断方法
特点:操作简单,但只能判断是否有泄漏,但需使用者自行判断泄漏在哪里
命令行方式
adb shell dumpsys meminfo vStudio.Android.Camera360 -d
结果如图:
Android Studio
1、选中机器和进程,点击箭头所指按钮
2、点击Memory Usage
示例
例如,若需检测取景页是否有内存泄漏
先在首页检测一次
此时Native Heap占用20M
进入取景页再检测一次,此时占用53M
可见取景页目前占用了33M内存
然后反复进入同时检测,如果每次进入NativeHeap都有增加,那肯定是泄漏了
2、进阶诊断方法
假设前面确实检测出底层内存泄漏了,怎么办呢?
如果你是一个能把代码倒背如流的高手,同时灵光一闪,想起哪儿出的问题,那么恭喜你问题解决了
否则,我们还是借助工具进行下一步吧
背景
Android Studio 的DDMS 下有一个隐藏的功能 “native heap”,能够分析底层内存泄漏,但是这个玩意很难用,以下攻略都是围绕如何把它用起来
1、判断ROM是否支持
需要ROM里system/lib目录里有libc_malloc_debug_leak.so和libc_malloc_debug_qemu.so
最简单的判断方式是
adb shell getprop ro.build.type
有三种类型:
user、userdebug、eng
如果是user,那肯定不行,如果是后两者,恭喜你,可以进行下一步了
愿意倒腾的,可以尝试去刷机,CyanogenMod是userdebug
嫌麻烦的,直接用Android Studio的模拟器
2、下载Tools
native heap这个功能在API18之后就被删掉了,因此必须下载API18或之前的tools
Linux:https://dl-ssl.google.com/android/repository/tools_r18-linux.zip
Windows:https://dl-ssl.google.com/android/repository/tools_r18-windows.zip
Mac:https://dl-ssl.google.com/android/repository/tools_r18-macosx.zip
下载好之后,先备份一下原先sdk下面的tools目录,比如说改个名字什么的,然后把这个新的tools
目录放到sdk目录下
3、配置DDMS
Linux: ~.androidddms.cfg
Windows:c:C:Users用户名.androidddms.cfg
Mac:不知道
如果没找到这个文件的,先打开DDMS一次,就会生成这个文件
在里面加一行
native=true
4、设置参数
需要打开内存泄漏检测的开关
adb shell setprop libc.debug.malloc 1
adb shell stop
adb shell start
记得检查一下是否设置上
C:UsersXXX>adb shell getprop libc.debug.malloc
1
看到返回1的话就是设置成功了
如果没成功,可能是需要root权限
5、开工
建议先关掉Android Studio,然后打开tools目录下的ddms
选中指定进程,然后点Snapshot Current Native Heap Usage
结果如下图
下面Stack Trace里面就是调用栈
6、调用栈解析
想要将调用栈解析为函数名及行号,首先需要带符号表的so库
然后按下列步骤:
C:UsersXXX>adb shell getprop libc.debug.malloc
#adb shell
# ps|grep cc.zgeek.facedemo
u0_a47 8090 2232 533156 45976 ffffffff b6f1b5a8 R cc.zgeek.facedemo
获取到PID为8090
# cat /proc/8090/maps |grep libPinguoImageSDK.so
979aa000-987c8000 r-xp 00000000 fe:20 81935 /data/app-lib/cc.zgeek.facedemo
-1/libPinguoImageSDK.so
987c9000-9881d000 r--p 00e1e000 fe:20 81935 /data/app-lib/cc.zgeek.facedemo
-1/libPinguoImageSDK.so
9881d000-988b9000 rw-p 00e72000 fe:20 81935 /data/app-lib/cc.zgeek.facedemo
-1/libPinguoImageSDK.so
如果有多个,选r-xp的那个,可知内存起始地址为979aa000
以这两行为例
内存地址为:
97c5fc6c-979aa000= 2B5C6C
97c5218c-979aa000=2A818C
知道内存地址后,就可以通过llvm-symbolizer工具(clang编译)者addr2line工具(gcc编译)将内存地址转换成可读的源码文件地址与行数。
这些工具可以在ndk工具包的toolchains目录下找到
操作命令如下:
1、创建临时文件
vim tmp.txt
2、录入以下内容,并保存
libPinguoImageSDK.so 0x2B5C6C
libPinguoImageSDK.so 0x2A818C
3、执行命令
llvm-symbolizer < tmp.txt
4、命令行输出内容即为内存地址与源码地址的对应关系,比如
void pugi::impl::(anonymous namespace)::xpath_ast_node::step_fill<pugi::impl::(anonymous namespace)::axis_to_type<(pugi::impl::(anonymous namespace)::axis_t)7> >(pugi::impl::(anonymous namespace)::xpath_node_set_raw&, pugi::xml_attribute const&, pugi::xml_node const&, pugi::impl::(anonymous namespace)::xpath_allocator*, pugi::impl::(anonymous namespace)::axis_to_type<(pugi::impl::(anonymous namespace)::axis_t)7>)
/Users/camera360/Documents/projects/c360/PGMakeupDemo/app/src/main/PinguoImageSDK_Android_OpenGL/ImageSDK/pugixml.cpp:7855:0
pugi::impl::(anonymous namespace)::utf_decoder<pugi::impl::(anonymous namespace)::utf8_counter, pugi::impl::(anonymous namespace)::opt_false>::decode_wchar_block(wchar_t const*, unsigned int, unsigned int)
/Users/camera360/Documents/projects/c360/PGMakeupDemo/app/src/main/PinguoImageSDK_Android_OpenGL/ImageSDK/pugixml.cpp:1000:11
可见,前面图中
这一行总计3044053bytes=2.9MB的空间被用于存储xml解析数据
如果退出相应界面之后这部分空间仍然存在,则可以认为是内存泄漏
最后
以上就是伶俐鞋子为你收集整理的Android Native内存泄漏诊断Android Native内存泄漏诊断的全部内容,希望文章能够帮你解决Android Native内存泄漏诊断Android Native内存泄漏诊断所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复