Android 内存泄漏分析

2019-09-21  本文已影响0人  董江鹏

Android目前较常遇到内存的问题是内存泄漏,而且这类问题不会像内存溢出直接崩溃那么明显,导致某些开发者不够重视。但App内存泄漏会浪费大量内存,也会引发频繁的垃圾回收,影响系统性能,可能是Google也意识到了滥用内存的严重性,在Android新推的架构组件Jetpack中就开始简化内存的维护工作。

我们可以用命令:

adb shell dumpsys meminfo <package>

查看App的内存使用情况


dump_memory.png

这里我们重点关注一下activities的数量,如果退出再进某个界面多次,内存里的activity数量增多,很明显就是发生了内存泄漏,activity退出后没有被回收。

接下来,我们需要找到那些对activity持有的强引用,
使用的工具依然是我们的老朋友DDMS,选择我们需要查看的进程,点击Update Heap,就可以在右侧看见当前进程的内存使用情况。这里我们可以手动触发垃圾回收,点击Gause GC几次,activity数量、内存占用没用明显减少,就说明可能有内存泄漏的问题。

ddms_memory.png
接下来,我们需要分析整个内存,需要将当前进程的内存情况存成文件,方便分析搜索。点击Dump HPROF file按钮,即可保存到本地。
这里我们需要另外一个工具,MemoryAnalyzer。
官网在此:
https://www.eclipse.org/mat/

此时我们本地的文件还不能被这个工具正常打开,还需要进行一下格式转换,Android SDK提供了格式转换的工具,
用这个命令转换一下:

hprof-conv input.hprof output.hprof

用MAT打开转换后的文件,我们直接看每个class的引用情况Hostogram:


mat_view.png

在Class Name下搜索我们需要查看的类名,比如MainActivity

mat_mainactivity.png

这里我们发现MainActivity当前有11个引用,这些引用还包括虚引用、弱引用和软引用,这些引用类型不会造成内存泄漏,我们需要排除,只留下强引用


mat_exclude.png
mat_leak.png

很明显,这里是广播在退出的时候没有取消注册,导致内部的数据结构一直持有已经退出的activity引用。

这些工具还是很强大很方便的,愿大家玩得开心。

上一篇下一篇

猜你喜欢

热点阅读