1, 内存泄漏的根本原因在于生命周期长的对象持有了生命周期短的对象的引用
2, 常见场景
(1) 资源对象没关闭造成的内存泄漏 (如: Cursor,File 等)
(2) 全局集合类强引用没清理造成的内存泄漏 (特别是 static 修饰的集合)
(3) 接收器, 监听器注册没取消造成的内存泄漏, 如广播, eventsbus
(4)Activity 的 Context 造成的泄漏, 可以使用 ApplicationContext
(5) 单例中的 static 成员间接或直接持有了 activity 的引用
(6) 非静态内部类持有父类的引用, 如非静态 handler 持有 activity 的引用
3, 如何避免内存泄漏
(1) 编码规范上:
1资源对象用完一定要关闭, 最好加 finally
2静态集合对象用完要清理
3接收器, 监听器使用时候注册和取消成对出现
4context 使用注意生命周期, 如果是静态类引用直接用 ApplicationContext
5使用静态内部类
6结合业务场景, 设置软引用, 弱引用, 确保对象可以在合适的时机回收
(2) 建设内存监控体系
线下监控:
1使用 ArtHook 检测图片尺寸是否超出 imageview 自身宽高的 2 倍
2编码阶段 Memery Profile 看 App 的内存使用情况, 是否存在内存抖动, 内存泄漏, 结合 Mat 分析内存泄漏
线上监控:
1上报 App 使用期间待机内存, 重点模块内存, OOM 率
2上报整体及重点模块的 GC 次数, GC 时间
3使用 LeakCannery 自动化内存泄漏分析
总结:
上线前重点在于线下监控, 把问题在上线前解决; 上线后运营阶段重点做线上监控, 结合一定的预警策略及时处理
4, 真的出现低内存, 设置一个兜底策略
低内存状态回调, 根据不同的内存等级做一些事情, 比如在最严重的等级清空所有的 bitmap, 关掉所有界面, 直接强制把 App 跳转到主界面, 相当于 App 重新启动了一次一样, 这样就避免了系统 Kill 应用进程, 与其让系统 kill 进程还不如浪费一些用户体验, 自己主动回收内存
来源: http://www.jianshu.com/p/90688135c9cf