Android Studio没有提供直接的Native层的内存泄露检测工具,但我们仍可以通过开源工具进行动态检测和静态检测
动态检测
在APP运行时进行检测,就像LeakCanary
Update: LeakTracer只能在简单的场景下检测Native层代码;复杂项目,比如依赖多个native module, 或者依赖其他module的native代码,或者依赖的不是Native代码而是so库,就容易出现漏报误报的情况。所以目前还没发鲁棒性较强的动态检测内存泄露的工具,欢迎推荐~
使用方法:
1.调用leaktracer::MemoryTrace::GetInstance().startMonitoringAllThreads();
表示开始检测;
2.调用
leaktracer::MemoryTrace::GetInstance().writeLeaks(out);
表示结束检测。
记得给予APP文件读写权限,不然会write失败。
3.将文件拿到手:
adb pull /sdcard/leaktracer.log
leaktracer.log文件包含泄露时间(time以秒为单位)、调用堆栈的地址信息、内存泄漏的大小等:
# LeakTracer report diff_utc_mono=1496511718.682943
leak, time=135120.534718, stack=0x36fd6 0x35a90 0x359a4 0x32fea 0xc952d3d0, size=1, data=.....
- 使用
leak-analyze-addr2line脚本批量定位
或者
按Android JNI Crash定位步骤的步骤定位泄露的具体位置
其中libleaktracer部分的泄露提示是可以忽略的,只需要关注项目自身部分。
注意: 一定要用未strip的so文件,不然堆栈信息会是问号
demo github地址: AndroidLeakTracerExample
使用tip:
开始检测前请先杀掉APP进程, 然后重启APP, 不然连续检测时, 后面的检测结果会不准.
-
Android原生开发--用Valgrind排查内存问题
文章里的工具我在两台root的小米设备上都没有弄成功;
另一个Valdroid项目我在一台root的小米设备上运行成功了,但是却没有打印日志。大概是因为这个项目是14年的,目前的手机很多配置和之前不一样了,所以不再适用。
感觉即使工具运行成功了,最后能不能有效检测出问题也不确定,所以先暂时放一边。毕竟实践的人少,而且谷歌也已经弃用不推荐了,肯定坑也多。 -
CheckJNI
11年就出品的工具,网上有一些资料,接入也不算麻烦。但一直没火起来还是有原因的:
我写了几号数组越界的代码,要么直接Crash,要么没检测出来,接了和没接一样,摊手.jpg
静态检测
有人推荐cppcheck
安装使用倒挺简单的, 但我故意写了内存泄露的代码
short* buffer = new short[8];
却没有检测出来。网上搜了一下,有人说
cppcheck is essentially only a style-checker
然后又试了一下valgrind
仍然没效果。
也可能是cppcheck和valgrind能检测出部分的代码错误,但不保证所有错误都检测出来,那检测一下也没坏处。
- malloc_debug / malloc & hook
爱奇艺出的hook框架可以检测内存泄漏 xHook
Android Native 内存泄漏系统化解决方案
Malloc Debug/README.md
Android malloc_debug介绍
其他参考:
Android内存泄漏简介
Android native内存检测(asan/malloc_debug)
Tip:
8.0以后Bitmap对象的内存放到Native里了。要及时回收Native 内存,需要调用一下Bitmap.recycle方法
网友评论