MAT修复APP内存泄漏实践

    本文章不着重讲解MAT的安装和基本操作(会推荐文章给大家看),只讲一下其用于优化项目的真实实践,MAT只有在Eclipse的ADT中有,虽然Android Studio有其一部分功能但是还是不完善的,MAT是android堆内存分析的神器,性能优化必须要会使用这个工具。

     MAT使用和安装请参考:内存分析工具MAT的使用

 引入                                                                                                

    近日看到荔枝TV(爱奇艺的TV版本)的运行内存有点高,操作一下就跑到100M以上去了,有点飙高啊,我掐指一算,肯定是内存泄露了。下面是APT内存监控分析图(APT腾讯的一款APP性能监控eclipse插件):



   使用MAT分析,下面是MAT的工具栏,一栏小按钮,第二,三,四个按钮都会用到。



     简单来说第二第三个按钮都是查看运行堆中到底是什么,只是分类的标准不一样,

              第二个是以基本数据类型和引用数据类型(比如int,String等等)分类,显示为柱状图,

              第三个是以android中的基本控件(比如Bitmap,Activity等等)来分,显示为树形结构图
          上面的分析不太对,请看这个:http://chiyx.iteye.com/blog/1528782  

 排查                                                                                                

     说一下简单的使用技巧,比如想要看看某一个页面(Activity为例)是否有泄露,我们可以多次进入退出,反复个好几次,再GC后在使用MAT查看堆内存,如果内存优化得好,就算是反复进入退出,内存也不会增大多少,总体趋势是起伏的。要是内存优化不给力,那么就是反复进入退出后内存没有减少多少,总体趋势是一只上升的。下面是第三个按钮查看的结果:



    这个app需要显示很多图片,所以会有很多bitmap,据我查看AlbumActivity就是我反复进入和退出的Activity,在我查看的时候我已经推出了这个Activity,但是我退出并GC后这个Activity还存在于堆内存中,这是排查内存泄漏的切入点,好吧,现在堆里面还残留着该死但是还没死的Actiivty,那么我是有sql语句查看一下,点击工具栏的第三个按钮,输入select * from instanceof android.app.Activity 可查看有多少个activity:




     其实也可以不这样,你确定要看某一个Activity你可以在筛选栏输入正则表达式  .*AlbumActivity.*


   具有差不多的效果,这个时候真是吓尿了,这个不该存在的Activity在堆内存中有8个,大大的内存泄漏啊,接下来就是看看为啥这逼这么老不死了:

 分析                                                                                                

    List Objects       

     在某一项上右键打开菜单选择 list objects ->with incoming refs 将列出该类的实例,它展示了对象间的引用关系。


      

    Path To GC Roots              

    被JVM持有的对象,如当前运行的线程对象,被systemclass loader加载的对象被称为GC Roots, 从一个对象到GC Roots的引用链被称为Path to GC Roots, 通过分析Path to GC Roots可以找出JAVA的内存泄露问题,当程序不在访问该对象时仍存在到该对象的引用路径,它可以快速找出某个实例没被释放的原因。

   


   使用 Path To GC Roots 看看AlbumActivity为什么没有被释放:


  我们可以看到由于Activity的context传递给了MicoWindowVideoView,我猜测可能是播放器,播放器的时候最是要注意了,一旦没有被及时回收就GC不掉,MicoWindowVideoView没有被及时回收,MicoWindowVideoView有持有AlbumActivity的引用Context,所以此Activity也一直存在于堆内存中,反复几次就会有多个存在了,针对此内存泄露,我的建议是在退出Activity时 及时回收资源,及时remove播放器的各种监听器,可以使用弱引用,实在不行就在创建播放器的时候传入ApplicationContext,不至于播放器一直持有AlbumActivity的引用,导致其无法被回收。

  总结                                                                                                

   相信对于android内存的问题我们都遇见过,总得来说规则也就那几条,退出及时回收资源,能置空的就都置空,免得GC的时候还要去处理判断对象之间是否存在引用,handler使用弱引用,context导致内心泄露可以使用applicationContext,等等,希望大家不管是做多么小的app,我们都谨慎点,app是我们生的亲儿子。哈哈哈,扯了这么多蛋,我要去撸代码了。

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值