

基于对象可达性原理解决Handler引起内存泄露问题
source link: https://zhuanlan.zhihu.com/p/136144855
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

基于对象可达性原理解决Handler引起内存泄露问题
这篇文章是刚工作不久时分享的,今天整理文档时发现了,今天把它整理到知乎上。记录工作中曾经做过哪些事情,等三四十年后(如果知乎微信还存在的话),坐在摇椅上回忆,也许会热泪盈眶吧。
Handler是Android开发者进行消息传递的常用api,然而随着开发者的使用不当或者不谨慎很容易引起内存泄露问题。严重时会造成几MB的内存空间被占用从而提高了OOM的发生概率和APP的崩溃率。
常见的解决方案
在 Activity 中避免使用非静态内部类,将 Handler 声明为静态的,则其存活期跟 Activity 的生命周期就无关了。同时通过弱引用的方式引入 Activity,避免直接将 Activity 作为 Context 传进去,即使用静态内部类 + WeakReference 这种方式
上述方案的缺点
实现方式过于复杂,需要在每个使用的地方都要生命一个静态内部类,如果我们需要多个Hand1er进行消息传递就需要声明多个,然后逐一进行实例化并且每次使用前注意判空。失去了原生Handler的简约性。
最优解决方案
内存泄露原因主要是由于Activity的销毁本应该伴随着垃圾回收而释放内存,但是由于Handler匿名内部类的持有而是内存无法及时回收掉。为此对Java垃圾回收机制进行了调研。Java垃圾回收机制判断该对象是否可以被回收掉是通过可达性分析算法。换种思路思考Activity无法释放的原因是由于被Activity的生命周期管理类和Handler类强可达造成的。随着Activity生命周期的结束Activity的生命周期管理类自然失去了对Activity的强可达,而Handler类随着消息的存在仍然对Activity强可达造成Activity无法释放内存。因此我们对Android原生的Handler进行的包装(WubaHandler)使原生的Handler弱可达WubaHandler,这样原生的Handler到Activity的可达路径变成弱可达就不会再影响Acitvity的内存释放。
基于java对象可达性原理本文实现了WubaHandler类,图一为该类的类图,图二为使用原生Handler的可达性图,图三为使用该类后的可达性图,从图二与图三可达性对比可以看出使用该类后Activity只被Activity的生命周期管理类强可达而Handler到Activity的可达路径变为了弱可达。从而避免的Handler导致Activity内存泄露问题。
WubaHandler类图(图一)
图一使用原生Handler可达性图(图二)
使用WubaHandler可达性图(图三)
- 开发者不必在意内部如何实现,同Handler使用方式一致,提高开发效率
- 摒弃了原生Handler内存泄露的缺点,从而降低了APP的奔溃率和OOM问题
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK