一、 手机端准备工作
1、 安装库文件
所有的 native 内存分配函数 ( malloc , calloc , etc.) 都在 Android 的 libc 库中。为了跟踪堆内存的分配,需要使用这个库的特别版本,可以将每次内存开销记录下来。 这些特殊版本的 libc ( libc_malloc_debug_leak.so and libc_malloc_debug_qemu.so 可以在手机中的/system/lib 下查看是否有这两个库 ) 只包含在eng或者user-debug版的 Android中。 如果手机是这两种系统之一,可以跳过下一步。
①下载最接近你手机模型和 Android系统版本( 2.3 、 4.0 等)的 CyanogenMod ROM 。如果没有恰好是你手机的对应版本,那么选择处理器相同的 ( 比如 Tegra2) 和 Android系统版本(例如 2.3 )都相同的 rom. 。然后从 system/lib 文件夹 抽出 libc_malloc_debug_leak.so 和 libc_malloc_debug_qemu.so 。
②以中兴 U880 手机为例,手机本身是移动定制的 Android2.2 系统, CyanogenMod 官网上恰有中兴的 rom,但是系统版本为 2.3.7 ,并且手机需要 root 权限,所以使用 U880 刷机工具,刷U880_2.3.7 root 版 rom 。
2、 替换库
①从 CM 版 rom 中 /system/lib 文件夹中抽出 libc_malloc_debug_leak.so 和 libc_malloc_debug_qemu.so
②把 libc_malloc_debug_leak.so 和 libc_malloc_debug_qemu.so 通过 USB拷到 SDCARD卡根目录下。
③手机中安装 BusyBox 以便使用 cp 命令复制文件。
④PC端命令行中执行
adb shell su mount
不同手机返回的值不同,如下两例
LG G2x:
...
/dev/block/mmcblk0p1 /system ext3 ro,noatime,errors=continue,data=ordered 0 0
...
中兴 U880 :
...
/dev/block/ mtdblock11 /system yaffs2 ro,relatime,barrier=1,data=ordered 0 0
...
第一部手机将 /dev/block/mmcblk0p1 作为设备, ext3 作为文件系统类型。
第二部手机将 /dev/block/ mtdblock11 作为设备, yaffs2 作为文件系统类型。
⑤使用上面得到的设备名,和文件系统类型,重新挂载系统分区为读写格式。如下所示:
LG G2x:
mount -o remount,rw -t ext3 /dev/block/mmcblk0p1 /system
中兴 U880 :
mount -o remount,rw -t yaffs2 /dev/block/ mtdblock11 /system
⑥ 把两个库文件从S DCARD 拷到 /system/lib 目录:
cp /sdcard/libc_malloc_debug_leak.so /system/lib/libc_malloc_debug_leak.so cp /sdcard/libc_malloc_debug_qemu.so /system/lib/libc_malloc_debug_qemu.so
⑦ 设置权限
chmod 0644 /system/lib/libc_malloc_debug_leak.so chmod 0644 /system/lib/libc_malloc_debug_qemu.so
3、 配置
① 替换完新的库文件后,告知系统使用新的库分配内存。
②命令行中执行
adb shell su setprop libc.debug.malloc 1
支持的参数:
1 - perform leak detection 5 - fill allocated memory to detect overruns 10 - fill memory and add sentinels to detect overruns 20 - use special instrumented malloc/free routines for the emulator
|
③ 重启框架 ,命令行中继续执行
stop start
如果命令成功,设备将在 1、 2 秒后重启, 注意并不是完全重启。
④ 检查配置
输入:
getprop
将会得到很多信息,其中包括:
...
[libc.debug.malloc]: [1]
...
说明配置成功
二、PC设置
在C:\Documents and Settings\Administrator\.android\ ddms.cfg 文件末尾添加
native=true
三、检查泄露
从SDK\tools 中启动独立的 DDMS ( ddms.bat )可以看见 native heap 选项卡
点击snapshot current... 按钮就可以了,如果按下±按钮,在点击 snapshot current 可以比较两次之间新分配了哪些空间。
有人说使用自己用源码编译出来DDMS 和模拟器,下面的 stacktrace 中的 File 和 Line 列就有值了。我们用的是真机啊。。。没有关系 ~~
找到自己的库函数***.so 后面的 Method 列中的地址。使用 NDK 中的 addr2line 工具,
用法:在命令行中addr2line.exe -e ***\obj\local\armeabi\***.so 地址
注意,一定要是obj 底下的 .so , lib 里面的是不含有符号表的。另外 Method 中的地址一般要将高 3 位置 0 , 80cc6e22 变为 000c6e22 。 80dxxxxx 的怎么变自己领悟吧。。。