码迷,mamicode.com
首页 > 其他好文 > 详细

深度分析内存泄漏原因,使用MAT工具检测内存泄露和性能

时间:2016-04-18 13:46:56      阅读:301      评论:0      收藏:0      [点我收藏+]

标签:

造成内存泄漏原因:

场景一:静态变量导致的内存泄漏

例如:mainactivity中

  private static context scontext;

   @override

    protected void oncreat(bundle savedinstancestate){

    .............................................

    scontext=this;

   }

泄漏点:静态变量scontext引用,activity无法正常销毁

场景二:单例模式导致的内存泄漏

    存在一个testmanager类,可以接收外部的注册并将外部的监听器存储起来;接着让activity实现一个ondatalistener接口并向testmanager注册监听,由于过程中缺少解注册的操作引起内存泄漏,原因activity的对象被单例模式的testmanager持有,单例模式特点是其生命周期和application保持一致,因此activity对象无法被及时释放

场景三:属性动画导致的内存泄漏

如果在activity中播放动画没有在ondestroy中去停止动画,那么动画会一直播放,尽管界面没有动画效果,并且这个时候的activity的view会被动画持有,导致activity无法释放,解决方案:在activity的ondestroy中调用animator.cancel()停止动画


Android Studio的界面 原生内存监测

技术分享


一般情况下,高密度的手机,一个页面大概就会消耗20M内存,如果发现退出界面,程序内存迟迟不降低的话,可能就发生了严重的内存泄露。 

我们可以反复进入该界面,然后点击dump java heap 这个按钮,然后Android Studio就开始干活了,下面的图就是正在dump 

技术分享技术分享

dump成功后会自动打开 hprof文件,文件以Snapshot+时间来命名 

技术分享技术分享


通过Android Studio自带的界面,查看内存泄露还不是很智能,我们可以借助第三方工具,常见的工具就是MAT了,下载地址 http://eclipse.org/mat/downloads.php,下载独立版的MAT. 下图是MAT一开始打开的界面, 这里需要提醒大家的是,MAT并不会准确地告诉我们哪里发生了内存泄漏,而是会提供一大堆的数据和线索,我们需要自己去分析这些数据来去判断到底是不是真的发生了内存泄漏。

技术分享技术分享

接下来我们需要用MAT打开内存分析的文件, 上文给大家介绍了使用Android Studio生成了 hprof文件, 这个文件在哪里?在Android Studio中的Captrues这个目录中,可以找到 

技术分享技术分享


注意,这个文件不能直接交给MAT, MAT是不识别的, 我们需要右键点击这个文件,转换成MAT识别的。 

技术分享技术分享


然后用MAT打开导出的hprof(File->Open heap dump) MAT会帮我们分析内存泄露的原因 

技术分享技术分享


技术分享



技术分享


LeakCanary

上面介绍了MAT检测内存泄露, 再给大家介绍LeakCanary。 
项目地址:https://github.com/square/leakcanary

LeakCanary会检测应用的内存回收情况,如果发现有垃圾对象没有被回收,就会去分析当前的内存快照,也就是上边MAT用到的.hprof文件,找到对象的引用链,并显示在页面上。这款插件的好处就是,可以在手机端直接查看内存泄露的地方,可以辅助我们检测内存泄露 

技术分享

技术分享

技术分享

技术分享


应用运行起来后,LeakCanary会自动去分析当前的内存状态,如果检测到泄漏会发送到通知栏,点击通知栏就可以跳转到具体的泄漏分析页面。 
Tips:就目前使用的结果来看,绝大部分泄漏是由于使用单例模式hold住了Activity的引用,比如传入了context或者将Activity作为listener设置了进去,所以在使用单例模式的时候要特别注意,还有在Activity生命周期结束的时候将一些自定义监听器的Activity引用置空。 
关于LeakCanary的更多分析可以看项目主页的介绍,还有这里http://www.liaohuqiu.net/cn/posts/leak-canary-read-me/




追踪内存分配

如果我们想了解内存分配更详细的情况,可以使用Allocation Traker来查看内存到底被什么占用了。 
用法很简单:

技术分享技术分享


点一下是追踪, 再点一下是停止追踪, 停止追踪后 .alloc文件会自动打开,打开后界面如下:

技术分享技术分享


当你想查看某个方法的源码时,右键选择的方法,点击Jump to source就可以了

查询方法执行的时间

Android Studio 功能越来越强大了, 我们可以借助AS观测各种性能,如下图: 

技术分享

技术分享

如果我们要观测方法执行的时间,就需要来到CPU界面 

技术分享技术分享

点击Start Method Tracking, 一段时间后再点击一次, trace文件被自动打开, 

技术分享技术分享

非独占时间: 某函数占用的CPU时间,包含内部调用其它函数的CPU时间。 
独占时间: 某函数占用CPU时间,但不含内部调用其它函数所占用的CPU时间。

我们如何判断可能有问题的方法?

通过方法的调用次数和独占时间来查看,通常判断方法是:

如果方法调用次数不多,但每次调用却需要花费很长的时间的函数,可能会有问题。 如果自身占用时间不长,但调用却非常频繁的函数也可能会有问题。




深度分析内存泄漏原因,使用MAT工具检测内存泄露和性能

标签:

原文地址:http://blog.csdn.net/lzq19931007/article/details/51177144

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!