今天原本想写一篇关于Android studio+Mat分析内存泄漏的博客,后来发现Android Studio实在太好用了,不需要Mat也可以很好的分析内存泄漏,等后面AS无法满足分析内存泄漏的要求再写Mat工具的使用。
Android Studio版本:4.1.2
第一步:生成prof文件
在Profiler中监测应用进程后,多操作几遍“进入、退出”想要检查是否有内存泄漏的页面,然后按照下图所示生成hprof文件
第二步:查看内存泄漏情况
第三步:分析内存泄漏
按照下图所示可以定位到内存泄漏的原因是自定义的MyView持有SecondActivity导致内存泄漏
第四步:查看代码
原来是静态变量持有SecondActivity导致内存泄漏。
以上就是关于使用Android Studio分析内存泄漏的使用,当然这只是很简单的一个使用方法,还有更多功能等你发现。
下面简单列出Android中存在内存泄漏的情况:
1.static变量引起的内存泄漏
因为static变量的生命周期是在类加载时开始 类卸载时结束,也就是说static变量是在程序进程死亡时才释放,如果在static变量中 引用了Activity 那么 这个Activity由于被引用,便会随static变量的生命周期一样,一直无法被释放,造成内存泄漏。
解决办法:
在Activity被静态变量引用时,使用 getApplicationContext 因为Application生命周期从程序开始到结束,和static变量的一样。
2.线程造成的内存泄漏
线程执行时间很长,即使Activity跳出还会执行,因为线程或者Runnable是Acticvity内部类,因此握有Activity的实例(因为创建内部类必须依靠外部类),因此造成Activity无法释放。
AsyncTask 有线程池,问题更严重
解决办法:
1.合理安排线程执行的时间,控制线程在Activity结束前结束。
2.将内部类改为静态内部类,并使用弱引用WeakReference来保存Activity实例 因为弱引用 只要GC发现了 就会回收它 ,因此可尽快回收
3.BitMap占用过多内存
bitmap的解析需要占用内存,但是内存只提供8M的空间给BitMap,如果图片过多,并且没有及时 recycle bitmap 那么就会造成内存溢出。
解决办法:
及时recycle 压缩图片之后加载图片
4.资源未被及时关闭造成的内存泄漏
比如一些Cursor 没有及时close 会保存有Activity的引用,导致内存泄漏
解决办法:
在onDestory方法中及时 close即可
5.Handler的使用造成的内存泄漏
由于在Handler的使用中,handler会发送message对象到 MessageQueue中 然后 Looper会轮询MessageQueue 然后取出Message执行,但是如果一个Message长时间没被取出执行,那么由于 Message中有 Handler的引用,而 Handler 一般来说也是内部类对象,Message引用 Handler ,Handler引用 Activity 这样 使得 Activity无法回收。
解决办法:
依旧使用 静态内部类+弱引用的方式 可解决
6.属性动画导致的内存泄露
属性动画有一类无限循环的动画,animation.setRepeatCount(ValueAnimation.INFINITE). 如果在activity中播放此类动画且没有在onDestroy中去停止动画,那么动画会一直播放下去 ,尽管已经无法在界面上看到动画效果,Activity的View会被动画持有,而View又持有Activity,最终Activity无法释放。
解决方法:
在Activity的onDestroy中调animator.cancel()
其中还有一些关于 集合对象没移除,注册的对象没反注册,代码压力的问题也可能产生内存泄漏,但是使用上述的几种解决办法一般都是可以解决的。
参考资料:https://blog.csdn.net/u012760183/article/details/52068490