内存泄漏的场景和解决办法

245 阅读3分钟

1.非静态内部类的静态实例
非静态内部类会持有外部类的引用,如果非静态内部类的实例是静态的,就会长期的维持着外部类的引用,组织被系统回收,解决办法是使用静态内部类

2.多线程相关的匿名内部类和非静态内部类
匿名内部类同样会持有外部类的引用,如果在线程中执行耗时操作就有可能发生内存泄漏,导致外部类无法被回收,直到耗时任务结束,解决办法是在页面退出时结束线程中的任务

3.Handler 内存泄漏
Handler 导致的内存泄漏也可以被归纳为非静态内部类导致的,Handler 内部 message 是被存储在 MessageQueue 中的,有些 message 不能马上被处理,存在的时间会很长,导致 handler 无法被回收,如果 handler 是非静态的,就会导致它的外部类无法被回收,解决办法是1.使用静态 handler,外部类引用使用弱引用处理 2.在退出页面时移除消息队列中的消息

4.Context 导致内存泄漏
根据场景确定使用 Activity 的 Context 还是 Application 的 Context,因为二者生命周期不同,对于不必须使用 Activity 的 Context 的场景(Dialog),一律采用Application 的 Context,单例模式是最常见的发生此泄漏的场景,比如传入一个 Activity 的 Context 被静态类引用,导致无法回收

5.静态 View 导致泄漏
使用静态View 可以避免每次启动Activity 都去读取并渲染View,但是静态 View 会持有 Activity 的引用,导致无法回收,解决办法是在 Activity 销毁的时候将静态 View 设置为 null(View 一旦被加载到界面中将会持有一个 Context 对象的引用,在这个例子中,这个 context 对象是我们的 Activity,声明一个静态变量引用这个 View,也就引用了 activity)

6.WebView 导致的内存泄漏
WebView 只要使用一次,内存就不会被释放,所以 WebView 都存在内存泄漏的问题,通常的解决办法是为 WebView 单开一个进程,使用 AIDL 进行通信,根据业务需求在合适的时机释放掉

7.资源对象未关闭导致
如 Cursor,File 等,内部往往都使用了缓冲,会造成内存泄漏,一定要确保关闭它并将引用置为 null

8.集合中的对象未清理
集合用于保存对象,如果集合越来越大,不进行合理的清理,尤其是入股集合是静态的

9.Bitmap 导致内存泄漏
bitmap 是比较占内存的,所以一定要在不使用的时候及时进行清理,避免静态变量持有大的 bitmap 对象

10.监听器未关闭
很多需要 register 和 unregister 的系统服务要在合适的时候进行 unregister,手动添加的 listener 也需要及时移除