Android开发中常见的内存泄漏的现象:举栗子
现象一:连续多次打开应用之后,界面卡顿,动画不流畅
现象二:操作过程中,LogCat频繁输出GC日志:
垃圾回收的现象:
垃圾回收之后
初步推断:频繁的打印GC日志,说明系统频繁触发GC来释放内存,初步判断可能存在内存泄漏
辅助验证工具:DDMS(设备的截图、虚拟地理位置、针对特定的进程查看对应的信息)
使用:
第一步:选中需要测试的进程
第二步、点击upHeap按钮,DDM通知应用,告诉他我可能要收集内存信息了!(准备)
第三步、点击Heap标签,展示应用的内存信息
第四步、点击Cause GC,DDMS应用的内存信息,log出来
查看信息:
连续打开应用,观察Total Size变化,验证是否有内存泄露
反复打开应用,观察Total Size变化
Total Size 随着打开次数的增加逐步增大,确实存在内存泄漏
内存泄露的原因:
MAT工具:主要能够分析内存中的状态以及所使用的内存的大小
MAT分析的过程:
思路:分析内存中占用比较大的对象
工具:Dominator Tree:能够列出所有对象,以及他们占用的内存大小
Dominator Tree截图
筛选之后的截图
最后查找的原因:
验证分析是否正确:
思路:查看内存中是否存在多个有Tread持有,导致无法回收的activtiy 实例
方法:Histogram:列出内存中所有的类,以及每个类的实例个数
内存中11个无法回收的Activity实例,由此判断,这里存在内存泄露
找到对应的代码:
根据代码分析:其内存泄露的根本原因:长生命周期对象(Tread)持有短生命周期对象(Activity)的引用,而导致的内存泄露
解决方案:
方案一:将Tread移到后台服务,使Tread和Activity解除依赖关系
举栗子:Tread功能和activity联系不是很紧密的时候:缓存数据的Tread
方案二:Activity退出时,停止Tread,使Tread与Activity的生命周期保持一致
更多案例:
构造Adapter时,没有使用缓存converView
正确写法:
不当的使用Context
总结: