Android系统(31)--- 如何分析native memory leak

 如何分析native memory leak

   分析native程序发生内存泄漏问题,就需要对每一笔内存申请做记录,释放内存时清除记录,然后在认为存在内存泄漏时将记录提取出来分析,看看在哪段代码存在申请的内存没有释放。
不过native进程申请内存的方法很多,可以直接通过mmap映射内存,也可以通过传统的堆分配函数malloc分配内存。这里我们只关注通过堆分配函数引起的内存泄漏。
Android有提供这部分内存泄漏的调试方法,但这个仅适用于app进程,对于其他native进程则需要另外的方法。
 
[ 1. 打开内存监控功能( 必须使用eng或userdebug版本)。
Android有提供堆调试功能
打开方法如下:
KK及以前版本:开机后用adb输入:
  adb shell setprop persist.libc.debug.malloc 15
  adb shell setprop persist.libc.debug15.prog  mediaserver
  adb shell setprop persist.debug15.config 0x24003024
  adb reboot
  adb shell setprop persist.libc.debug.malloc 1
  adb reboot
L及之后版本:在vendor/mediatek/proprietary/external/aee/config_external/init.aee.customer.rc添加:
on init
export LD_PRELOAD libsigchain.so:libudf.so
重新打包bootimage并下载, 开机后用adb输入:
  adb shell setprop persist.libc.debug.malloc 15
  adb shell setprop persist.libc.debug15.prog  mediaserver
  adb shell setprop persist.debug15.config 0x4a003024
  adb reboot
O及之后版本:直接adb:
  adb shell "echo libc.debug.malloc.options="backtrace=8" >> /data/local.prop"
  adb shell "echo libc.debug.malloc.program=  mediaserver >> /data/local.prop"
  adb shell "chmod 644 /data/local.prop"
  adb reboot

其中红字部分修改为要监控的 可执行文件名。
 
2. 检查是否存在内存泄漏。
打开mtklogger,不断通过adb shell procrank -u > procrank.txt查看当前系统内存的使用情况。
当看到被监控的进程占用内存(USS字段)超过了正常值很多,则可能存在内存泄漏。
 
3. 得到该进程内存使用分布情况($pid为被监控进程pid)
adb shell dumpsys meminfo $pid >meminfo_$pid.txt
adb shell procmem $pid > procmem_$pid.txt
 
4. 抓取该进程的coredump。
adb shell kill -5 $pid
 
5. 抓取coredump和mtklog。可以用GAT的bugreport功能一键抓取log。将以上这些抓取的coredump和log提供到e-service给MTK分析。
6. 现在这种问题也可以自行分析,用E-Consulter(mtk online的工具栏搜索得到)分析,会给出分析报告,如果存在超过128M以上的泄漏,那么分析报告会提示如下:
 == C堆检查 ==
分配器: dlmalloc, 最多允许使用: 4GB, 最多使用: 188MB, 当前使用: 166MB, 泄露阈值: 128MB, 调试等级: 1

该堆已分配超过128MB (可能存在内存泄露), 以下列出分配最大尺寸和次数的调用栈:
大小: 1184字节, 已分配: 134604次
分配调用栈:
 libc_malloc_debug_leak.so 0x40D5ECD4() + 16
 libc_malloc_debug_leak.so leak_malloc() + 43
 libc.so malloc() + 18
 libsqlite.so sqlite3MemMalloc() + 14 <external/sqlite/dist/sqlite3.c:15298>
 libsqlite.so mallocWithAlarm() + 86 <external/sqlite/dist/sqlite3.c:18862>
 libsqlite.so sqlite3Malloc() + 16 <external/sqlite/dist/sqlite3.c:18895>
 ......
 == 栈结束 ==

大小: 1184字节, 已分配: 5149次
分配调用栈:
 libc_malloc_debug_leak.so 0x40D5ECD4() + 16
 libc_malloc_debug_leak.so leak_malloc() + 43
 libc.so malloc() + 18
 libsqlite.so sqlite3MemMalloc() + 14 <external/sqlite/dist/sqlite3.c:15298>
 libsqlite.so mallocWithAlarm() + 86 <external/sqlite/dist/sqlite3.c:18862>
 ......
 == 栈结束 ==

大小: 1048584字节, 已分配: 1次
分配调用栈:
 libc_malloc_debug_leak.so 0x40D5ECD4() + 16
 libc_malloc_debug_leak.so leak_malloc() + 43
 libc.so malloc() + 18
 libsqlite.so sqlite3MemMalloc() + 14 <external/sqlite/dist/sqlite3.c:15298>
 libsqlite.so mallocWithAlarm() + 86 <external/sqlite/dist/sqlite3.c:18862>
 libsqlite.so sqlite3Malloc() + 16 <external/sqlite/dist/sqlite3.c:18895>
 ......
 == 栈结束 ==
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值