本文将分析Android native memory的使用状况及通过一些手段来定位到native memory leak代码。
在EngLoad上执行以下adb命令
$ adb shell setprop libc.debug.malloc 1 $ adb shell stop $ adb shell start
然后等手机重新启动后,链接DDMS就可以看到每个SO文件占用的内存大小了。一般占用很大的比较可能发生内存泄露。
(此图片引用自网络)
还有一种复杂的分析方法是结合process showmap, process maps及 process coredump3个文件来定位内存泄露代码,此方法可以直接定位到内存泄露代码,但需要是ENG版的手机和工程symbols文件。
首先,从process showmap文件中找出占用Memory最大的.so文件。
362148 289012 288412 0 648 0 288634 1590 [anon:libc_malloc]
可以看到上面native分配占用了288412 Bytes约288M内存。
然后,输入arm-linux-androideabi-gdb进入gdb
(gdb)file <product_name>/symbols/system/bin/app_process (需要调试的程序)
(gdb)set solib-search-path <product_name>/symbols/system/lib(设置搜索的Symbols文件)
(gdb)core-file coredump (即process coredump文件) (检查内存及寄存器)
(gdb)source core_parser_leak_info_v0.1.gdb(解析内存分配点)
可以看到
alloc_size = alloc_num * size_per_alloc
270MBytes = 49252 * 5760
alloc_bt:
bt:0x7a215c
bt:0xfffffffc
接着,从process maps中可以看到
0064f000-008d0000 r-xp 00000000 b3:05 1296 /system/lib/libskia.so
由于0x7a215c 在libskia.so的地址范围内0064f000-008d0000,可以断定是libskia.so发生了内存泄露。
计算地址偏移0x7a215c - 0064f000 = 0x0015315c
最后,使用arm-linux-androideabi-addr2line 来定位代码
arm-linux-androideabi-addr2line -C -f -e <product_name>/symbols/system/lib/libskia.so 0x15315c
SkImageDecorder::onDecodeSubset(SkBitmap* , SkIRect const&)
external/src/images/SkImageDecorder_libjpeg.cpp:2874
参考文献:http://source.android.com/devices/native-memory.html