手记

Android应用Native内存调试技巧

Native内存调试,或许大部分Android开发者不怎么能接触到这一块,因为Native一般由底层C++工程师进行调试的,如果从事Android系统开发的哥们应该会用得到这一块。所以这个方向在网上的资料比较少,谷歌官方在Android开发者网站(developer.android.com)提到的内存调试仅限于JAVA层。官方只有在Android Open Source Project网站(source.android.com)上才有提及Naitve内存调试的相关信息。好了,废话就说到这了。现在开始着手Naive内存调试的开始。

本文需要使用到的工具有

1、Android Sdk

2、Android Emulator(Sdk里有)

3、NDK(https://dl.google.com/android/repository/android-ndk-r12b-linux-x86_64.zip)

4、DDMS(https://dl.google.com/android/repository/tools_r25.2.3-linux.zip)

当然,还有android项目,so库等,这些就不一一列举了,毕竟本文的重点是内存调试。注:本文开发环境是linux。所以(NDK和DDMS)下载地址仅限linux环境。

一、DDMS解除封印,“Native Heap”选项开启

在安卓开放源码项目(https://source.android.com/devices/tech/debug/native-memory)中提到。

You can also use the Dalvik Debug Monitor Server (DDMS) to obtain a graphical view of Malloc Debug output.

To use DDMS, first turn on its native memory UI:

  1. Open ~/.android/ddms.cfg

  2. Add the line: native=true

意思就是说打开当前用户配置目录下的.android目录里的文件ddms.cfg配置文件进行修改。

在文件记录的末尾新增一行,加上native=true。修改保存后,重启ddms即可。(window环境下是在C:\Documents and Settings\$user\.android\ddms.cfg)

Native Heap如图所示

二、打开模拟器,打开模拟器malloc的debug模式

在终端输入以下命令:

adb shell setprop libc.debug.malloc 1

adb shell stop

adb shell start

这个阶段模拟器会进行重启。这里特别说明一下为什么教程不用真机进行,因为真机/system/lib目录下没有debug版本的malloc库( libc_malloc_debug_leak.so 和 libc_malloc_debug_qemu.so)。如果一定要使用真机调试的话,可以从原生系统的模拟器或者真机中拷贝这2个库,然后赋予0644权限,再调用以上命令即可。

三、进行Native内存调试

打开DEMO项目,点击New  100M MEMORY的Button。我在Button调用的Native方法里面申请了100M的运行内存,并且不进行释放。用于模拟Native内存泄漏的情况。

选择DEMO的运行进程com.example.spence.myapplicationcplus,然后在ddms中点击snapshot current native heap usage按钮。

这时出现了一个错误提示,提示讲找不到本地的库文件,我们点ok后。如图所示

可以看到Native heap选项窗口中展示了目前内存占用的情况,以及调用的次数。method方法名这个时候显示的是在当前运行系统中内存的地址。这么看不够直观。那么我们来让显示变得更直观一点。

四、进行NDK地址映射

NDK里面有个好东西可以帮助我们让方法显示更直观。那就是NDK里的arm-linux-androideabi-addr2line工具。要使用这个工具,必须配置此工具路径到环境变量。arm-linux-androideabi-addr2line工具的路径为android-ndk-r12b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin

配置完环境变量后,还需要在Symbol Search Path填入so库的名字,此处填入DEMO项目的so库路径MyApplicationCPlus/app/build/intermediates/cmake/debug/obj/x86/即可。

然后再点击snapshot current native heap usage按钮。出现如下图所示。

这次我们可以看到已经清晰的显示出了Method的名称,并且在Stack Track窗口还显示了具体调用代码的行号。便于我们对相关占用内存的代码进行查看。

DEMO工程里的Native代码目前是内存泄漏的,例如我们再点击New  100M MEMORY的Button3次,那么会得到如下图所示

我们可以看到Library窗口中,DEMO工程的SO库方法Java_com_example_spence_myapplicationcplus_MainActivity_stringFromJNI显示Count为4,这代表目前被调用了4次。也就是说通过定位代码方法和次数,可以进行Native内存泄漏的检测。

注:如果项目中有多个so库,在Symbol Search Path中用:进行隔开路径就好,如果都在同一目录下就不需要隔开。

如果有什么不明白的欢迎大家留言提问。

DEMO工程的下载链接: https://pan.baidu.com/s/1qXLAv9q 密码: ftq8

http://www.apkbus.com/thread-276228-1-1.html

原文链接:http://www.apkbus.com/blog-176164-68234.html

1人推荐
随时随地看视频
慕课网APP