赞
踩
内存泄漏的根本原因是一个长生命周期对象持有一个短生命周期对象,造成短生命周期对象没有办法被回收所导致的。
常见的有:
1.内部类形式使用handler同时发了延迟消息,这时候退出activity会造成activity内存泄漏。AsyncTask同理会造成内存泄漏。
2.单例类持有activity会造成activity内存泄漏。
3.各种注册操作没有对应反注册(广播,eventbus等)。
我们分析内存泄漏的时候一定要想清楚整体的引用链关系,根据根节点可达性算法一个GCROOT持有activty那么就会造成其内存泄漏,比如上述handler的情况,handler内部类持有外部类引用,sendmessage的时候message会持有handler,enqueueMessage会造成messageQueue持有message,而如果发的是延迟消息那么message并不会立即的遍历出来处理而是阻塞到对应的message触发时间以后再处理,那么阻塞的这段时间中activity关闭就会造成内存泄漏。
整体的引用链关系就是activity->handler->message->messagequeue(GCROOT)
同理asyncTask也是,由于asyncTask中任务都是串行执行的,如果某一个任务比较耗时或有太多的任务需要处理,那么就有可能发生内存泄漏。
整体的引用链关系就是activity->asynctask->Thread(GCROOT)
解决的方法如上就是将内部类定义为静态内部类,但是静态内部类引用不到外部类的非静态属性和方法,所以可以用弱引用持有外部类,通过弱引用去调用外部类的属性和方法,同时由于弱引用自身如果只有一个对象持有它则在GC时会被直接回收的特性,所以不用担心有内存泄漏的风险。
检测的话LeakCanary可以检测,源码网上有很多文章,大家有兴趣自己看一下吧~
以上是我个人想法,欢迎一起探讨哈~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。