最近在Android项目中遇到C++层内存泄露问题,在此记录解决方法。
1.修改C:\Users\\.android\ddms.cfg,在文件的最后添加"native=true"。
2.连上真机并打开cmd命令行,执行以下几步:
adb root //获取root
adb shell setprop libc.debug.malloc 1 //设置检测等级,这里的1表示检测内存泄露,其他参数可百度
adb shell stop
adb shell start
setprop libc.debug.malloc 1 这一步需要真机中有以下两个文件:/system/lib/libc_malloc_debug_leak.so 与 /system/lib/libc_malloc_debug_qemu.so。
可以使用adb shell进入shell模式查看这两个文件是否存在(使用linux控制台指令)。
adb shell start这步之后可以使用 adb shell getprop查看libc.debug.malloc有没有设置为1。
3.打开ddms.bat,这个文件在sdk/tools里,我的路径是F:\adt-bundle\sdk\tools\ddms.bat。
这里的ddms和adt中的ddms不一样,会多出一个native heap选项卡。
左侧的列表窗口会显示真机中的所有进程,选择需要检测的进程(你的项目包名),
然后点下"Snapshot Current Native Heap Usage"按钮,之后就会显示native层的内存分配情况。
method那一栏会显示进行分配内存的函数地址。
点击上图中的"+-"按钮,可以在每次点击"Snapshot"按钮之后显示内存增加情况。
定位到内存分配异常的那条,记录下method的地址,然后通过下面几步获得具体函数。
4.记录左侧的列表窗口中需要检测的进程的pid,打开cmd命令行,输入adb shell进入shell模式,再输入 cat proc/pid/maps。
输入之后会打印很多进程的符号表,找到你的.so的起始地址,例如:5f930000 - 6a000000 ..... libTest.so,
这里的5f930000就是起始地址。如果libTest.so之前有多个地址,使用第一个(这个不确定,如果最终定位的函数很奇怪,
就试试其他的吧)。
5.将D:\android-ndk-r9b\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\bin添加到环境变量PATH
中(这里的目录需要根据你的目标平台设置)。添加到PATH是为了方便使用这个目录下的gdb,
也就是arm-linux-androideabi-gdb.exe这个。配置好后打开cmd命令行,输入arm-linux-androideabi-gdb开启gdb。
然后输入 file ,gdb会载入共享库的符号表。
计算真实函数地址0xXXXXXXXX = method地址 - 上一步得到的起始地址。 之后输入 info symbol 0xXXXXXXXX 来定位函数。
通过以上步骤就可以定位到具体的函数了,如果有问题,欢迎留言。
参考网址:(这篇的寻找method地址有误)
http://www.360doc.com/content/14/0222/17/10366845_354796656.shtml