研究了一波Android Native C++内存泄漏的调试

2399次阅读  |  发布于3年以前

最近在调试Android Native层的内存泄漏问题,整理了一些笔记,分享一下

本文目录

如何查看内存信息?- 在代码中打印,开启一个线程,间隔固定时间打印出当前内存信息【有好多种获取内存信息的API,这里只列出其中一种方式,亲测有效】

private void startMemProfiler() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                displayMemory();
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }).start();
}

private void displayMemory() {
    final ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
    activityManager.getMemoryInfo(info);
    Log.i(TAG, "系统剩余内存:" + (info.availMem / (1024 * 1024)) + "M");
    Log.i(TAG, "系统是否处于低内存运行:" + info.lowMemory);
    Log.i(TAG, "当系统剩余内存低于" + (info.threshold / (1024 * 1024)) + "M" + "时就看成低内存运行");
    Log.i(TAG, "系统已经分配的native内存:" + (Debug.getNativeHeapAllocatedSize() / (1024 * 1024)) + "M");
    Log.i(TAG, "系统还剩余的native内存:" + (Debug.getNativeHeapFreeSize() / (1024 * 1024)) + "M");
    Log.i(TAG, "系统的所有native内存大小:" + (Debug.getNativeHeapSize() / (1024 * 1024)) + "M");
}

adb shell dumpsys meminfo /
adb shell dumpsys meminfo tv.danmaku.bili

dumpsys meminfo显示的信息如图所示:

Android 关键内存项介绍

这里仅介绍我们需要重点关注的字段:

如何调试内存泄漏

matrix的使用

通过集成matrix库,可以选择hook某个动态链接库的malloc和free符号,然后工作方式和libctools类似,存储malloc的节点,free时候就删除该节点,最后统计内存泄漏情况。

matrix的集成方式可以看github库:https://github.com/Tencent/matrix

hook的原理可以看:https://github.com/iqiyi/xHook/blob/master/docs/overview/android_plt_hook_overview.zh-CN.md

如果出现内存泄漏,会有json和log后缀的文件,如图:

json文件会统计哪个库泄漏了多少内存,log文件会记录具体泄漏的堆栈信息。

拿到具体泄漏的堆栈信息后,可以通过addr2line工具定位到具体的代码:

/Users/xxx/Android/ndk/21.4.7075529/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android-addr2line -C -f -e /Users/xxx/project/java/build/intermediates/stripped_native_libs/debug/out/lib/arm64-v8a/libBMMCapture-Android.so 83a70

效果如图:

其它工具

dumpsys还有一些其它功能,使用方式如下:

复盘拍摄内存泄漏排查

背景:每次出现内存泄漏时,经常怀疑是某个模块或者其他库更新导致,但又没有证据,没有合适的排查内存泄漏的方法论。

分析与解决:

■接入每个三方库时,都写一个Demo,进行效果测试、内存测试、性能测试,每次更新三方库时,都跑一下Demo。或者每次出问题时,跑一下Demo看是不是这个库导致的问题。

■集成第三方库时,降低代码耦合性,保证可以灵活去掉某个三方库,可考虑使用条件编译等手段,方便排查问题。

■引入工具排查:

○内存泄漏:Android使用matrix,iOS使用Xcode

○cpu占用率:Android profiler, iOS Xcode

○gpu占用率:Android 高通使用snapdragonprofiler,或者perfdog(收费)


参考资料

https://developer.android.com/studio/command-line/dumpsys

https://blog.csdn.net/pugongying1988/article/details/16838859

https://www.jianshu.com/p/8203457a11cc

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8