内存泄漏的根本原因之一就是长生命周期持有短生命周期对象的引用,导致内存泄漏
何时需要查看应用内存是否泄露
- 开发时当Logcat频繁打印GC日志的时候,说明系统在频繁的触发GC来释放内存
- 测试使用中在打开应用一段时间后,应用卡顿甚至崩溃(crash)
- 产品发布前的最后检查
你可能会需要使用到的工具有什么
子曰:“工欲善其事,必先利其器”,好用的工具往往使我们事半功倍。
- 使用Android Device Monitor中的
DDMS
工具查看应用内存占用
- 打开Android Device Monitor,选择DDMS
- 点击需要检测的应用,选择Update Heap,查看Heap选项卡,点击Cause GC,记录Total Size信息
- 连续打开应用,观察Total Size变化,验证是否有内存泄漏
如果Total Size随着打开次数的增加逐步增大,则确实存在内存泄漏
-
Android Device Monitor中还有一个神器,常用于分析内存较大的对象的时候可以使用
Dominator Tree
工具
例如:查看Bitmap对象到GC Roots的引用路径
-
Eclipse下想要分析具体内存信息,可以使用MAT工具 :http://www.eclipse.org/mat/downloads.php
-
Android Studio内部已经集成内存分析工具
常见内存泄露场景有哪些
- 界面已退出,但是Thread仍然持有着Activity的引用,导致Activity和它所占用的内存都不能被释放回收
内存中存在11个无法回收的Activity实例,由此判断,这里存在内存泄漏
解决方法:
- 将Thread移动到后台服务,是Thread与Activity解除依赖关系
- Activity退出时,停止Thread,使Thread与Activity的生命周期保持一致
- 构造Adapter时,在getView方法中重复使用LayoutInflater构建视图对象,而不判断该对象是否已经存在
Adapter的getView方法会根据显示的View数目多次调用,因此在此处应避免构建新的对象,不仅仅能解决内存泄漏的问题更能优化体验
- 不当的使用上下文对象
当不得不使用上下文对象获取应用资源时,尽量使用ApplicationContext,而非当前Activity中的Context
再未来的开发生涯中如何尽量避免
- 深刻理解每个对象的生命周期
- 善于利用各种工具分析定位问题
- 规范代码编写