一、MAT工具:内存分析的“瑞士军刀”
1. 安装与启动
-
下载地址:
-
核心功能模块:
- Overview:内存快照概览(总大小、类数量等)
- Histogram:对象直方图(按类统计实例数)
- Dominator Tree:支配树(按内存占用排序)
- OQL控制台:对象查询语言(精准定位问题对象)
2. 内存快照捕获技巧
- 触发GC:在dump前手动触发GC(
Debug.startAllocTracing()),减少噪声数据 - 过滤系统库:在MAT中勾选
Keep unreachable objects,避免系统库干扰分析 - 多快照对比:连续操作后多次dump,通过对比定位内存增长点
二、内存分析“四步法”
Step 1:概览分析
- 检查
Total Count和Total Size是否异常(如超过200MB需警惕) - 关注
Retained Heap占比高的类(尤其是自定义类)
Step 2:Dominator Tree定位
-
按
Retained Heap降序排列 -
展开前十大对象,检查是否包含:
- 未销毁的Activity/Fragment
- 缓存未释放的Bitmap/大数组
- 第三方SDK的意外残留
Step 3:路径追踪
-
右键可疑对象 →
Path To GC Roots→ 排除Weak/Soft/Phantom引用 -
典型泄漏路径示例:
MyActivity -> View -> Handler -> MessageQueue -> Looper -> Thread
Step 4:OQL精准打击
-
常用查询语句:
sql -- 查找所有未关闭的Cursor SELECT * FROM android.database.Cursor WHERE isClosed() = false -- 统计Bitmap数量及大小 SELECT toString(s), sizeof(s) FROM INSTANCEOF android.graphics.Bitmap s -- 查找持有Activity的匿名内部类 SELECT * FROM INSTANCEOF java.lang.ref.WeakReference WHERE toString().contains("Activity")
三、线程分析:揪出内存抖动的元凶
1. 线程视图入口
-
Thread Overview:展示所有线程及其状态 -
重点关注:
Runnable线程数量(正常应<10)- 线程栈中的自定义类(如
MyTask)
2. 典型问题场景
-
线程池泄漏:
ThreadPoolExecutor -> Worker -> Runnable -> MyTask -> MyActivity修复方案:使用
Executors.newSingleThreadExecutor()替代手动管理线程。 -
AsyncTask未取消:
AsyncTask$1 -> MyActivity修复方案:在
onDestroy中调用cancel(true)。
四、对比分析:量化内存变化
1. 操作步骤
- 生成操作前后的两个.hprof文件
- 在MAT中打开
Compare Basket视图 - 添加两个快照到对比篮
- 重点关注
Diff列变化,定位内存增长点
2. 实战案例
某应用在连续切换页面后内存增长50MB,通过对比分析发现:
MyAdapter$ViewHolder实例数从10激增至500- 进一步追踪发现
RecyclerView未正确复用ViewHolder - 修复方案:检查
getItemViewType和onBindViewHolder逻辑,确保复用机制生效
五、进阶技巧:内存问题的“根因分析”
1. 支配树优化
- 右键点击类 →
List Objects→with incoming references - 展示所有引用该对象的入口,快速定位泄漏源
2. 合并路径分析
- 右键多个可疑对象 →
Merge Shortest Paths to GC Roots - 找出共同引用链,定位公共泄漏点
3. 正则表达式过滤
-
在
OQL中使用正则表达式:sql SELECT * FROM INSTANCEOF java.lang.String WHERE toString().matches(".*leak.*")
六、总结:MAT工具的“降维打击”
MAT工具就像内存分析的“显微镜”,通过:
- Dominator Tree定位内存大户
- OQL查询精准扫描问题对象
- 线程分析揪出资源泄漏
- 对比分析量化内存变化
掌握这些技巧后,即使是复杂的内存泄漏问题也能迎刃而解。记住:内存优化没有银弹,但MAT绝对是你最趁手的“内存猎刀”。日常开发中建议养成以下习惯:
- 关键操作后手动触发GC并dump内存
- 定期进行自动化内存测试
- 对第三方库进行内存安全审查
通过系统化的内存分析,可以让应用在流畅度与稳定性上实现质的飞跃。