第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 文件,步骤如下:

  1. 连接设备或模拟器,确保目标进程正在运行。
  2. 在 Android Studio 中选择 View → Tool Windows → Profiler。
  3. 选择目标应用进程,进入 Memory 子标签。
  4. 点击 Dump Java Heap 按钮(垃圾箱图标旁的蓝色圆形按钮)。
  5. 等待 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 (对象未被GC回收) Dump Java Heap Memory Profiler 按钮 原始 .hprof Dalvik 虚拟机格式 导出 / 保存 hprof-conv -z 转换命令 标准 .hprof Java 标准格式 MAT / LeakCanary 分析 格式验证 文件头含 "JAVA PROFILE"
工作流要点:① 确认 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 按钮
未转换格式直接导入 MATMAT 报错 "Invalid heap dump format"使用 hprof-conv 转换或 Android Studio 导出时勾选转换选项
dump 过程中切换界面或杀进程快照损坏,无法打开保持应用在前台稳定运行,等待 Profiler 完成分析