Java Heap Dump(堆内存快照)

一、Heap Dump概述

常见扩展名.hprof

生成方式

  • 使用 jmap 工具:
    jmap -dump:format=b,file=heap.hprof <pid>
    
  • JVM 启动参数自动生成(如 OOM 时):
    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/heap.hprof
    

解析工具

1. Eclipse Memory Analyzer (MAT)
  • 官网:https://www.eclipse.org/mat/
  • 用法:
    1. 安装并打开 MAT。
    2. File > Open Heap Dump,选择 .hprof 文件。
    3. 自动分析内存泄漏嫌疑对象、对象引用链等。
2. VisualVM
  • 官网:https://visualvm.github.io/
  • 用法:
    1. 启动 VisualVM。
    2. File > Load,选择 .hprof 文件。
    3. 查看类实例、对象大小分布、GC Roots 路径等。
3. 命令行工具
  • jhat
    jhat heap.hprof
    
    启动后可通过浏览器访问 http://localhost:7000 进行分析(但较老旧,不推荐)。

总结

  • Heap Dump:用于分析内存对象分布和泄漏,推荐用 MAT、VisualVM。
  • Thread Dump:用于分析线程状态和死锁,推荐用 FastThread、jstack。
  • 解析 dump 文件时,关注对象引用链、GC Roots、线程锁关系等关键信息。

http://tool111.com

二、Heap Dump 详解

1. Heap Dump 文件结构

Heap Dump(如 .hprof 文件)本质上是 JVM 内存堆的快照,记录了:

  • 所有对象实例(包括类名、字段、引用关系、大小等)
  • 类定义信息
  • GC Roots
  • 线程信息(有时包含)
hprof 文件内容主要包括:
  • Header:文件头,标识为 hprof 格式
  • Records:一系列记录(如 LOAD CLASS、HEAP DUMP SEGMENT、STRING等)

2. 解析过程原理

解析 heap dump 的工具(如 MAT、VisualVM)大致遵循以下步骤:

步骤一:读取并解析文件结构
  • 解析 header,确定版本、字节序等
  • 顺序读取各个记录,建立对象、类、字符串等的索引
步骤二:重建对象图
  • 根据对象实例记录,重建堆中所有对象
  • 解析对象字段,将对象间的引用关系(指针)还原为图结构
步骤三:分析引用链和 GC Roots
  • 寻找 GC Roots(如静态变量、线程栈、JNI引用等)
  • 从 GC Roots 出发遍历对象图,分析哪些对象可达
  • 统计各个对象的大小、引用链,查找内存泄漏嫌疑对象(如大对象、长链条)
步骤四:生成报告
  • 统计各类对象的数量和大小
  • 展示对象之间的引用关系
  • 标记泄漏嫌疑对象、分析内存分布

核心原理
通过对象之间的引用关系,重建堆内存的对象图,并结合 GC Roots,分析对象生命周期和可达性。

三、HPROF文件结构

HPROF 文件结构总览

HPROF 文件主要由以下几部分组成:

  1. Header(文件头)
  2. Records(记录区)
    • 包含一系列类型不同的记录(如字符串、类加载、对象实例、堆快照等)

Header(文件头)

HPROF 文件头内容如下:

  • 格式标识:ASCII 字符串 "JAVA PROFILE 1.0.1"
  • 换行符\n
  • ID Size(4字节):指示后续所有 ID 字段(如对象ID、类ID等)的字节长度(通常为4或8字节)
  • 高精度时间戳(8字节):long 型,单位为毫秒

示例(16字节头部):

JAVA PROFILE 1.0.1\n
[idSize: 4字节]
[timestamp: 8字节]

Records(记录区)

HPROF 文件主体由一系列记录构成,每条记录结构如下:

字段长度说明
Tag1字节记录类型
Time4字节记录生成时间(相对文件头时间)
Length4字节记录内容长度
BodyLength字节记录内容

主要 Tag 类型

Tag (16进制)含义
0x01STRING
0x02LOAD CLASS
0x0ASTACK FRAME
0x0BSTACK TRACE
0x0CALLOC SITES
0x0FHEAP DUMP
0x1CHEAP DUMP SEGMENT
0x1DHEAP DUMP END

常见记录类型说明

1. STRING (Tag: 0x01)

记录字符串常量(如类名、字段名等)。

字段长度说明
String IDidSize字符串的唯一ID
UTF-8 字符变长字符串内容

2. LOAD CLASS (Tag: 0x02)

记录类的加载信息。

字段长度说明
Class Serial4字节类的序号
Class ObjectidSize类对象ID
Stack Trace4字节堆栈跟踪ID
Class NameidSize类名字符串ID

3. HEAP DUMP / HEAP DUMP SEGMENT (Tag: 0x0F/0x1C)

堆快照的主要内容,包含对象、类、数组等实例。

HEAP DUMP SEGMENT 结构:

由一系列子记录组成,每个子记录结构如下:

子Tag说明
0xFFROOT UNKNOWN
0x01ROOT JNI GLOBAL
0x21CLASS DUMP
0x22INSTANCE DUMP
0x23OBJECT ARRAY DUMP
0x24PRIMITIVE ARRAY DUMP
其他类型
重要子记录结构举例:
CLASS DUMP (0x21)

记录类定义,包括字段、方法等。

字段长度说明
Class ObjectIDidSize类对象ID
Stack TraceID4字节堆栈跟踪ID
Super ClassIDidSize父类对象ID
Class LoaderIDidSize类加载器对象ID
Name StringIDidSize类名字符串ID
Instance Size4字节实例大小
字段列表等
INSTANCE DUMP (0x22)

记录对象实例,包括字段值。

字段长度说明
ObjectIDidSize对象ID
Stack TraceID4字节堆栈跟踪ID
Class ObjectIDidSize类对象ID
Data Length4字节字段数据长度
Field Data变长字段值内容
OBJECT ARRAY DUMP (0x23)

对象数组实例。

字段长度说明
ArrayIDidSize数组对象ID
Stack TraceID4字节堆栈跟踪ID
NumElements4字节元素数量
ArrayClassIDidSize数组类型ID
ElementIDsidSize*N每个元素对象ID
PRIMITIVE ARRAY DUMP (0x24)

基本类型数组实例。

字段长度说明
ArrayIDidSize数组对象ID
Stack TraceID4字节堆栈跟踪ID
NumElements4字节元素数量
ElementType1字节元素类型(如int、byte等)
Values变长元素值

ID Size 与对象引用

  • HPROF 文件中的所有对象、类、字符串等都用 ID 表示,长度由文件头的 idSize 指定(通常为 4 或 8 字节)。
  • 这些 ID 用于在各个记录之间建立引用关系。

扩展说明

  • HPROF 格式在不同 JVM 版本间可能略有差异,建议使用主流工具(MAT、VisualVM)解析。
  • HPROF 也可以用于 CPU/线程分析,但现代 JVM 更推荐使用更高效的格式(如 JFR)。

总结

HPROF 文件由头部记录区组成,记录区通过不同的 Tag 标识不同类型的数据,如字符串、类定义、对象实例、数组等。解析 HPROF 文件时,需根据 Tag 和 idSize,逐条解析和关联各个对象与类的信息,最终重建 JVM 堆内存的快照结构。

创作不易,点赞关注,持续更新~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猩火燎猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值