AndroidStudio 内存泄漏的分析过程

前言部分

这次泄漏是自己代码写的太随意引起的,讲道理,代码写的太为所欲为了,导致有些问题根本就很难发现。

泄漏产生的原因,由于activity未被回收导致。这里给我们提出的一个警示,在使用上下文的时候,我们要特别注意,尤其是一些实例的上下文,如:activity、fragment等。

这次的错误原因就是我把activity作为上下文传给了Glide使用,结果后期我做夜间模式,需要重启activity让夜间模式生效的时候忘记Glide还在持有activity的引用导致了泄漏。

内容部分

产生了泄漏的时候我们需要一些分析工具,leakcanary算是一个必备工具了。我们通过leakcanary可以收集到app产生的泄漏信息,然后通过信息可以找到具体的类,定位到泄漏的类中,在顺着引用连接就可以找到了。下面看一个泄漏的图:

AndroidStudio 内存泄漏的分析过程_第1张图片
上图中可以看出一些重要信息:

MainActivity的实例发生了泄漏,这表明我们的MainActivity在实例销毁的时候由于被Glide引用,并没有被回收。

导致这个结果的原因就是下面这段代码:

Glide.with(this@MainActivity)
.load(R.drawable.head_photo)
  .apply(RequestOptions.bitmapTransform(CircleCrop()))
  .into(ivPersonPhoto!!)

这里传入Glide中的上下文我没有使用applicationContext,结果在启用夜间模式的时候进行重启activity的时候出现了泄漏。

一些简单的泄漏通过leakcanary帮助我们收集的信息是可以处理的。但是如果有很多地方都引用一个实例的话,我们就需要使用一下分析工具了。

下面我们来看一下如何通过studio查看泄漏的步骤

  1. 我们先通过操作产生泄漏,这个时候我们的内存已经出现了泄漏。
  2. 然后点击Profile如图:在这里插入图片描述
  3. 下面我们手动触发GC来回收无用的内存。如图:AndroidStudio 内存泄漏的分析过程_第2张图片
  4. 然后内存不在减少后我们点击一下小垃圾桶旁边的箭头。就可以获取到内存的情况了。
  5. 我们点击MainActivity这个类,在右侧我们发现有两个对象在内存中。AndroidStudio 内存泄漏的分析过程_第3张图片
  6. 点击后发现MainActivity被GlideRequests引用。如图
AndroidStudio 内存泄漏的分析过程_第4张图片

上面基本定位完成,这里我们在去找Glide引用MainActivity的地方就可以了。

上面讲的其实不太实用,因为实在通过leakcanary中确定MainActivity发生了泄漏,然后去直接去找的MainActivity,并且找到了Glide引用了MainActivity的实例才能顺利解决。

实际场景中还有很多复杂的内容,比如我的MainActivity可能被很多地方引用,找起来还是很麻烦的。所以这篇文章也只是最简单的应用。就像以前我写的查找应用超时的问题一样,基本也是找到trace文件,在里面找到自己项目相关的代码,在进行定位(猜测)。

结语部分

很多人都会问怎么进行内存泄漏的排查,其实我觉得更多的还是看经验了。因为有些泄漏真的是很难发现,如果是偶然才会发生的泄漏,那就真的更难查找了。

多学习积累一些经验会更好的帮助我们处理一些比较诡异的问题

你可能感兴趣的:(问题分析)