第3章 堆转储文件快照获取:通过 Android Studio Dump Java Heap 命令获取 hprof 并转换为标准格式
在现象识别之后,我们需要主动采集内存快照,锁定泄漏对象。堆转储(Heap Dump)是记录某个时刻 Java 堆中所有对象、引用关系及内存使用情况的快照文件(.hprof)。通过分析堆转储,可以找到本该被回收却仍被 GC Roots 引用的 Activity 实例。
3.1 数据采集的时机与原则
- 时机:必须在 Activity 已经执行
onDestroy()但内存中仍存在其对象时触发 dump。建议在反复执行“进入→退出”目标 Activity 3~5 次后立即 dump。 - 原则:避免在 dump 前主动调用
System.gc()(Android 不保证立即执行),也不要关闭 Activity 进程。只能使用 Dump Java Heap 而非 Force GC + Dump 模式。 - 多次对比:至少准备两个快照——一个在刚启动无泄漏场景时,一个在可疑操作后。通过比较对象实例数增量,快速定位泄漏类。
3.2 使用 Android Studio Profiler 获取堆转储
Android Studio 内置的 Memory Profiler 可直接生成 .hprof 文件,步骤如下:
- 连接设备或模拟器,确保目标进程正在运行。
- 在 Android Studio 中选择 View → Tool Windows → Profiler。
- 选择目标应用进程,进入 Memory 子标签。
- 点击 Dump Java Heap 按钮(垃圾箱图标旁的蓝色圆形按钮)。
- 等待 Android Studio 完成 dump 和分析,自动在堆转储列表中显示快照。
生成的 .hprof 文件默认存储在以下路径:
AndroidStudioProjects/YourApp/app/build/outputs/hprof/
技巧:点击 Profiler 中快照右侧的 Export 按钮,手动选择保存位置。建议文件名包含时间戳和操作场景,如
heap_before_leak_20250328.hprof。
3.3 转换为标准 MAT / LeakCanary 可分析格式
Android 原生生成的 .hprof 文件是 Dalvik 虚拟机格式,无法直接被 Eclipse MAT 或 Android Studio 内置的分析器正确解读。必须使用 hprof-conv 工具(位于 Android SDK platform-tools 目录)将其转换为标准 Java heap dump 格式。
转换命令行(Windows / macOS / Linux 通用):
hprof-conv -z input.hprof output.hprof
# -z 参数用于排除 Zygote 进程的共享内存,减少文件大小
如果不带 -z 参数:
hprof-conv heap_original.hprof heap_standard.hprof
注意:Android Studio 11.0 及以上版本在导出时默认已包含转换步骤(勾选“Convert to standard .hprof”),此时无需额外转换。但建议手动确认文件头部是否包含
java.io 标记,否则仍须使用 hprof-conv 处理。
3.4 验证转换结果
使用 MAT Headless 嗅探 快速检查格式是否合法:
# 在 MAT 安装目录下
parseHeapDump.sh heap_standard.hprof
# 或使用命令行查看文件头:head -c 32 heap_standard.hprof | od -c
标准 .hprof 文件的前 32 字节应包含 JAVA PROFILE 1.0.2 或 JAVA PROFILE 1.0.1 等字符串。
| 特性 | Dalvik 格式 .hprof | 标准 Java 格式 .hprof |
|---|---|---|
| 适用工具 | Android Profiler 内置分析 | Eclipse MAT / LeakCanary / JProfiler |
| 对象引用关系 | 包含 Android 特有对象类型 | 纯 Java 引用图 |
| 转换必要性 | 需转换后供 MAT 使用 | 无需转换 |
| 文件大小 | 较大(含 Zygote 数据) | 经 -z 转换后更小 |
3.5 快照获取与转换流程图
下图展示了从出现泄漏迹象的 Activity 到生成标准 .hprof 文件的完整数据采集链路,其中箭头表示操作流向,虚线框表示可选或工具辅助步骤。
工作流要点:① 确认 Activity 残留后立即 dump;② 使用 hprof-conv 转换时注意 -z 参数可减少大小;③ 将标准 .hprof 文件导入 MAT 前,建议先通过 Android Studio 的 Export to standard .hprof 按钮进行预览,避免多次命令行操作。
3.6 常见错误与避坑
| 错误场景 | 后果 | 解决办法 |
|---|---|---|
| 在 Activity 未 finish 时 dump | 看不到泄漏对象实例 | 确保已执行 onDestroy() 后等待若干秒再 dump |
| 使用 Force GC + Dump 替代 Dump Java Heap | 强制 GC 可能回收泄漏对象,快照无意义 | 始终使用 Dump Java Heap 按钮 |
| 未转换格式直接导入 MAT | MAT 报错 "Invalid heap dump format" | 使用 hprof-conv 转换或 Android Studio 导出时勾选转换选项 |
| dump 过程中切换界面或杀进程 | 快照损坏,无法打开 | 保持应用在前台稳定运行,等待 Profiler 完成分析 |