关于 Android 内存泄漏,几乎是面试中的必问题了,当然在我们平常开发过程中,也是很常见的问题啦,因此面试过程中呢,多多少少都会扯到这方面。
总之它就是面试必备问题之一啦。那么来小小总结一下有关 Android 内存泄漏。
关于内存泄漏的概念:
内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
常见的产生内存泄漏的情况:
持有静态的Context(Activity)或者 View 的引用。
内部类&匿名内部类实例无法释放(有延迟时间等等),而内部类又持有外部类的强引用,导致外部类无法释放,这种匿名内部类常见于监听器、Handler、Thread、TimerTask。
资源使用完成后没有关闭造成内存泄漏。例如:BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap,应该在 Activity 销毁时及时关闭或者注销,否则这些资源将不会被回收,造成内存泄漏。
不正确的单例模式,比如单例持有 Activity(由于Activity 生命周期比较短,当 Activity 退出的时候,它的内存无法回收造成内存泄漏),解决的话可以使用生命周期更长一点的 Application。
集合类内存泄漏,如果一个集合类是静态的(缓存HashMap),只有添加方法,没有对应的删除方法,会导致引用无法被释放,引发内存泄漏。
错误的覆写了finalize()方法,finalize()方法执行执行不确定,可能会导致引用无法被释放。
检测内存泄漏的方式:
- Android Profiler 工具
- LeakCanary 工具
避免内存泄漏:
定制好编码规范
不要对 activity 的 context 长期引用 ( 一个 activity 的引用的生存周期应该和 activity 的生命周期相同)
试着使用 application 的 context 来替代和 activity 相关的 context。
如果一个 acitivity 的非静态内部类的生命周期不受控制,那么避免使用它。
使用一个静态的内部类并且对其中的 activity 使用一个弱引用。
垃圾回收器不能处理内存泄漏的保障。