android native层 解析xml,Android Native内存泄漏诊断

Android Native内存泄漏诊断

1、基础诊断方法

特点:操作简单,但只能判断是否有泄漏,但需使用者自行判断泄漏在哪里

命令行方式

adb shell dumpsys meminfo vStudio.Android.Camera360 -d

结果如图:

0818b9ca8b590ca3270a3433284dd417.png

Android Studio

1、选中机器和进程,点击箭头所指按钮

0818b9ca8b590ca3270a3433284dd417.png

2、点击Memory Usage

0818b9ca8b590ca3270a3433284dd417.png

示例

例如,若需检测取景页是否有内存泄漏

先在首页检测一次

0818b9ca8b590ca3270a3433284dd417.png

此时Native Heap占用20M

0818b9ca8b590ca3270a3433284dd417.png

进入取景页再检测一次,此时占用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

3、配置DDMS

Linux: ~.android\ddms.cfg

Windows:c:C:\Users\用户名.android\ddms.cfg

Mac:不知道

如果没找到这个文件的,先打开DDMS一次,就会生成这个文件

在里面加一行

native=true

4、设置参数

需要打开内存泄漏检测的开关

adb shell setprop libc.debug.malloc 1

adb shell stop

adb shell start

记得检查一下是否设置上

C:\Users\XXX>adb shell getprop libc.debug.malloc

1

看到返回1的话就是设置成功了

如果没成功,可能是需要root权限

5、开工

建议先关掉Android Studio,然后打开tools目录下的ddms

选中指定进程,然后点Snapshot Current Native Heap Usage

0818b9ca8b590ca3270a3433284dd417.png

结果如下图

0818b9ca8b590ca3270a3433284dd417.png

下面Stack Trace里面就是调用栈

6、调用栈解析

想要将调用栈解析为函数名及行号,首先需要带符号表的so库

然后按下列步骤:

C:\Users\XXX>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

以这两行为例

0818b9ca8b590ca3270a3433284dd417.png

内存地址为:

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<:impl:: namespace> >(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)

/Users/camera360/Documents/projects/c360/PGMakeupDemo/app/src/main/PinguoImageSDK_Android_OpenGL/ImageSDK/pugixml.cpp:7855:0

pugi::impl::(anonymous namespace)::utf_decoder<:impl:: namespace pugi::impl::>::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

可见,前面图中

0818b9ca8b590ca3270a3433284dd417.png 这一行总计3044053bytes=2.9MB的空间被用于存储xml解析数据 如果退出相应界面之后这部分空间仍然存在,则可以认为是内存泄漏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值