美文网首页
解决Android内存泄漏—轻松降低100M

解决Android内存泄漏—轻松降低100M

作者: 蓝灰_q | 来源:发表于2016-12-02 19:48 被阅读734次

    背景

    今天发现有个App存在严重的内存泄漏问题,通过安装LeakCanary找到大致方向,通过严格管理Timer、Presenter和Handler,轻松把它消耗的内容降低了100M。

    过程

    LeakCanary

    LeakCanary是square公司提供的一个很好用的内存泄漏查找工具,与MAT不同的是,它会在你运行App时检查你的内存回收,并找到内存泄漏点,直接提示给你,比用MAT去分析日志的形式更加简单直接,不过缺点是LeakCanary的信息不像MAT那么多,很难查到更细微的问题。

    LeakCanary的安装过程很简单,首先配置Gradle

    为LeakCanary添加Gradle引用

    然后在自定义的Application中初始化

    在自定义的MyApplication中初始化LeakCanary

    记得在Manifest中使用自定义的Application

    在AndroidManifest中使用自定义的MyApplication

    运行App,LeakCanary会在App运行过程中不定期收集信息,如果发现有内存泄漏的问题,就会在通知栏中给出提示,如XXXActivity大概因为XXX泄露了XXM内存,比如我们运行LeakCanary在Github上的demo,得到的提示就会像下图这样

    LeakCanary典型界面

    可见,直接指出了问题类和问题原因,比起MAT还是简单多了的

    Timer

    在检查中,在Presenter里忘记关闭一个Timer的task,在Activity的onDestroy事件中调用Presenter的onDestroy

    在Activity关闭时调用Presenter的销毁函数

    在Presenter的onDestroy中执行销毁操作

    在Presenter中的销毁操作

    我们看到,在Presenter销毁元素时,做了三件事:

    1.关闭线程(要先执行interrupt,否则休眠线程无法立即停止)

    2.销毁Presenter中关联的View对象(否则会导致对应的Activity无法释放)

    3.退出Timer定时任务

    Presenter

    再看一遍Presenter执行销毁操作的代码

    Presenter销毁View

    在上图中,我们看到Presenter在销毁时,一定要把View销毁掉,否则会导致对应的Activity或Fragment无法释放,在检查中发现有些Presenter没有写销毁,考虑在以后统一实现一个Presenter的基类,在基类中实现销毁View的代码

    Handler

    在检查中,发现有些对话框弹出后无法回收内存,在检查中发现了这样的代码

    LeakHandler

    这是我们一般接触到的典型的Handler写法,但是注意看提示,提示中说明了这里有泄漏风险,从避免内存泄漏的角度,应该改成这样的代码

    AntiLeakHandler

    在这段写法中,我们用static内部类去重载了一个Handler,static内部类实际上会生成一个弱引用对象,这就不会产生内存泄漏。

    不过这样一来,在static内部类中,我们就无法调用Activity的函数了,这就需要在这个Handler初始化时把Activity传进来,直接传进来的Activity还是可能造成内存泄漏,我们还要把它放到一个弱引用对象里,通过get()函数取得Activity对象并调用其函数。

    总结

    在这次的内存泄漏查找过程中,主要解决了三个问题

    1.及时销毁所有的Timer定时任务

    2.及时销毁Presenter中的View对象

    3.检查所有的Handler,改为static+弱引用的实现方式

    解决这些问题后,再次运行LeakCanary,已经不再输出内存泄漏的内容了,App消耗的内存也减少了100多M。

    其实这里解决的内存泄漏问题都是很浅显的部分,能在这些地方出错,说明这个App的内存泄漏已经相当严重了,在日常编码中,还是要多留一份心才是。

    相关文章

      网友评论

          本文标题:解决Android内存泄漏—轻松降低100M

          本文链接:https://www.haomeiwen.com/subject/myeqmttx.html