MAT内存泄露分析(二)

宝贝中心头像切换

  • com.xtc.watch.view.widget.fancycover.FancyCoverFlowItemWrapper存在内存泄漏
  • Objects:

    《MAT内存泄露分析(二)》 这里写图片描述

  • path to gc roots:

    《MAT内存泄露分析(二)》 这里写图片描述

    从上面的gc roots来看,FactCoverFlowItemWrapper是被多个对象所持有的,无论怎样都是不能被释放的,在代码中创建FactCoverFlowItemWrapper的部分:

    《MAT内存泄露分析(二)》 这里写图片描述
    只要FactCoverFlowItemWrapper创建出来之后就无法被释放了,这个确实有点坑,在界面中
    《MAT内存泄露分析(二)》 这里写图片描述

    正常的话应该是有4个FactCoverFlowItemWrapper对象的,这里多出了3个,还会存在一个风险,如果手表解绑,那么应该溢出掉对应的FactCoverFlowItemWrapper对象,但是从gc roots来看,FactCoverFlowItemWrapper会一直被引用的,所以有可能解绑手表后对应的FactCoverFlowItemWrapper即使移除了也无法被及时回收。

微聊模块

  • ChatActivity

    《MAT内存泄露分析(二)》 这里写图片描述

    创建了5个activity对象导致ChatActivity里面的一些对象引用都没有被释放

    《MAT内存泄露分析(二)》 这里写图片描述
    Gc roots:
    《MAT内存泄露分析(二)》 这里写图片描述

    预测是activity退出了,但是AudioManager还在执行

  • VoiceMsg

    《MAT内存泄露分析(二)》 这里写图片描述

    代码中根本没有18条语音
    Gc roots:

    《MAT内存泄露分析(二)》 这里写图片描述
    这个原因应该是ChatActivity泄漏导致的,如果ChatActivity正常释放应该就正常了

  • ViewHolder

    《MAT内存泄露分析(二)》 这里写图片描述

    Gc roots:

    《MAT内存泄露分析(二)》 这里写图片描述

定位模块

  • com.xtc.watch.view.location.activity.LocationMainActivity
    gc roots:

    《MAT内存泄露分析(二)》 这里写图片描述

    这里倒是不会造成内存泄漏,只是在activity界面退出的时候没有及时取消ArcImageButton的动画,所以导致Activity无法立刻被回收,如果短时间内反复的进入退出定位界面,那么将会创建多个activity对象,然后等动画执行完了之后,这些activity才能在被gc的时候回收掉
    修改建议:把ArcImageButton动画在onDestroy方法里面取消掉

登录模块

《MAT内存泄露分析(二)》 这里写图片描述

由于MainActivity没有释放,所以导致里Bitmap占用的内存也没有被释放

《MAT内存泄露分析(二)》 这里写图片描述

MainActivity泄漏导致里面的Bitmap无法被回收,导致7.9MB的内存可能出现问题

《MAT内存泄露分析(二)》 这里写图片描述

Gc roots:

《MAT内存泄露分析(二)》 这里写图片描述

可能存在的问题代码MainActivity类:

《MAT内存泄露分析(二)》 这里写图片描述

进入主界面后MainActivity没有finish掉
修改建议:在启动HomePageActivity之后把MainActivity finish掉

通讯录模块

《MAT内存泄露分析(二)》 这里写图片描述

Gc roots:

《MAT内存泄露分析(二)》 这里写图片描述

《MAT内存泄露分析(二)》 这里写图片描述

《MAT内存泄露分析(二)》 这里写图片描述

《MAT内存泄露分析(二)》 这里写图片描述

代码问题:

《MAT内存泄露分析(二)》 这里写图片描述

umengSocialUtil在创建的时候直接使用当前activity对象作为参数,但是这个参数必须传activity对象,所以修改建议是:对UmengSocialUtil做修改,因为这个activity对象会保存到友盟分享sdk的一些类里面,当activity退出的时候把UmengSocialUtil里面的相关对象释放掉

修改设置类开关

com.xtc.watch.view.message.helper.MessageControl存在内存泄漏:

《MAT内存泄露分析(二)》 这里写图片描述

我反复gc,过了很久之后再次gc,上述对象依然没有被回收
Gc roots:

《MAT内存泄露分析(二)》 这里写图片描述

问题代码:

《MAT内存泄露分析(二)》 这里写图片描述

线程中执行的是数据库操作实现异步,但是我并不明白在子线程中加Looper.prepare()和Looper.loop()干嘛?又没有弹Toast?loop()方法是一个死循环,导致这个线程一直无法结束所以一直存在,因此线程中的对象无法被释放,同时这个线程也占用了内存资源

APP设置模块

  • XtcDescBookActivity

    《MAT内存泄露分析(二)》 这里写图片描述

    Gc roots:

    《MAT内存泄露分析(二)》 这里写图片描述
    上面可以看到是由于webkit在activity退出的时候没有destroy导致CleanupReferrece里面一直持有Context造成的泄漏
    修改建议:

    把webview首先从父控件中remove掉,然后再调用destroy方法

  • AboutActivity

    《MAT内存泄露分析(二)》 这里写图片描述

    Gc roots:

    《MAT内存泄露分析(二)》 这里写图片描述
    仍然是由于友盟分享工具类造成的activity引用被持有了
    修改建议:根据泄漏原因把友盟分享工具改改,在activity退出的时候显示的把引用设置为null

主界面

《MAT内存泄露分析(二)》 这里写图片描述

丫的我都已经退出登录了,正常的话主界面应该已经被回收了,所以不会再有HomePageActivity的对象存在了
Gc roots:

《MAT内存泄露分析(二)》 这里写图片描述

话不多,有几个地方同时持有了HomePageActivity的引用
修改建议:传参数Context的时候如果不是必须用Activity就尽量用全局的ApplicationContext,或者在Activity的onDestroy把一些引用手动设置为null,但是这个好像没用,搜索了网上的解决方案发现展示webview界面可以单独开启一个进程,退出后再杀死这个进程,这样就不会造成webview的内存泄漏了,个人觉得这个靠谱,可以尝试

单例内存问题

发现一个问题,当app使用了很多模块之后,有很多单例实现的ServiceImpl类其实在退出后可能并不会频繁的调用到,但是单例对象还是占用这内存的,虽然占用的内存非常小,有几十B,也有两三百B,优化建议:可以采用弱引用来持有单例

    原文作者:大大大大大先生
    原文地址: https://www.jianshu.com/p/367ba77872f5
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞