Android Studio Profiler 内存泄漏分析

最近的项目中出现了内存泄漏,在踩了好多坑之后,终于解决了遇到的泄漏问题,为了防止下次忘记,所以把这次的经验记录下来。

前言

内存泄漏有很多种的情况,在安卓里面,大多是因为内部类持有了Activity或者Context的引用导致Activity或者Context无法释放,最常见的是执行了一个耗时操作,在退出Activity的时候没有关闭耗时操作,导致Activity一直被耗时操作持有。
例如网上经常会有讲到使用Handler的时候需要注意泄漏,需要使用静态内部类,并且弱引用Activity解决。这样的地方可以在写代码的时候注意到然后解决,但是有些时候我们也不知道哪里出现了内存泄漏,就需要通过工具帮助我们分析了。

Android Studio Profiler

Android Studio自带的Profiler就提供了这样的能力,打开Profiler会看到如下的界面,


然后点击红色选框中的部分,就可以进入内存分析详情如下:

为了查看到内存泄漏,我们需要对app进行一顿操作。如果我们想知道一个TestActivity有没有内存泄漏,那么我们可以频繁的进出TestActivity,按照官网的说法横竖屏切换和回退到桌面再进入app也会增加泄漏的风险。一顿操作猛如虎,要知泄漏有没有,且看下面。
当我们频繁操作之后,可以先点击左上角的垃圾桶按钮,进行强制GC,多点几次,接下来点击左上角的下箭头图标生成分析文件,这就是我们判断有没有内存泄漏的关键。

为了方便查看,我们可以把分组方式改为按照包名分组

那么怎么看有没有泄漏呢?在左下角的堆窗口找到我们想要测试的那个class名,点击会出现如下的窗口:

其中左下角的HandlerActivityHandlerActivity$1可能第一次看会很迷,难道说我的这个类有两个实例吗,那不就是内存泄漏了么?其实并不是这个意思,$符号只是说明这个类有一个内部类而已,因为内部类会持有外部类的引用。
右上角的地方我们可以看到有四个HandlerActivity,那这个说明是内存泄漏了么?是的,这个Instance View就是实例窗口,有几个就说明有几个实例,如果按照逻辑这个对象同时只能有一个实例的话,那就是内存泄漏了。
当知道是内存泄漏之后就需要找到泄漏的地方,在右下角有一个引用窗口,可以看到具体是谁引用这个它,导致内存不能及时回收。在右上角的实例窗口选中一个实例,然后在引用窗口选中一条点击右键Jump to Source就可以看到具体引用的地方,然后观察代码就知道是什么问题导致的内存泄漏了。

Search by:GoogleBingBaidu