Go Wiki:heapdump13
其他版本的堆转储格式
- Go 1.4:heapdump14
- Go 1.5 及更高版本:heapdump15-through-heapdump17
简介
Go 1.3 添加了一个 runtime/debug.WriteHeapDump 函数,该函数将堆中的所有对象以及其他信息(根、goroutine、终结器等)写入文件。此文件的格式在此处指定。
详细信息
文件以字符串“go1.3 heap dump\n”的字节开头。
文件的其余部分是一系列记录。记录可以是几种不同的类型。记录将包含以下基元
- uvarint - 一个 64 位无符号整数,编码方式如 encoding/binary.{Put,Read}Uvarint
- string - 一个 uvarint 编码的长度,后跟该长度的字节数据
- bool - 一个 uvarint 编码的 0 表示 false,1 表示 true
- fieldlist - 对内存区域中包含指针的部分的描述。它由成对的 uvarint 组成,分别编码字段类型和字段偏移量,后跟一个结束列表标记。可能的类型为 1=Ptr、2=String、3=Slice、4=Iface 和 5=Eface。0=Eol 是结束列表标记。结束列表标记没有对应的偏移量。
每条记录都以一个 uvarint 编码的整数开头,该整数描述记录的类型
- 0 = EOF
- 1 = 对象
- 2 = 其他根
- 3 = 类型
- 4 = goroutine
- 5 = 栈帧
- 6 = 转储参数
- 7 = 已注册的终结器
- 8 = itab
- 9 = 操作系统线程
- 10 = 内存统计信息
- 11 = 排队的终结器
- 12 = 数据段
- 13 = bss 段
- 14 = defer 记录
- 15 = panic 记录
- 16 = 分配/释放配置文件记录
- 17 = 分配堆栈跟踪样本
每条记录的剩余字段都与类型相关,如下所述。
EOF
EOF 记录没有字段,并且必须最后出现。
对象
- uvarint:对象的地址
- uvarint:类型描述符的地址(如果未知,则为 0)
- uvarint:对象的类型(0=常规 1=数组 2=通道 127=保守扫描)
- 字符串:对象的内容
对于数组或通道类型,类型必须非零。
内容字符串的大小是包含的 sizeclass 的大小,而不是类型本身的大小。因此,内容大小可能比类型大小稍大。对于数组和通道类型,它可能会大很多。例如,具有 n 个元素的数组的内容大小将大于或等于类型大小的 n 倍。
其他根
- 字符串:此根来自何处的文本描述
- uvarint:根指针
类型
- uvarint:类型描述符的地址
- uvarint:此类型对象的 size
- 字符串:类型名称
- 布尔值:包含此类型值的接口的数据字段是否为指针
- fieldlist:此类型对象中包含指针的字段的类型和位置列表
goroutine (G)
- uvarint:描述符的地址
- uvarint:指向栈顶的指针(当前正在运行的帧,又称深度 0)
- uvarint:go 例程 ID
- uvarint:创建此 goroutine 的 go 语句的位置
- uvarint:状态
- 布尔值:是否为系统启动的 Go 例程
- 布尔值:是否为后台 Go 例程
- uvarint:go 例程上次开始等待的近似时间(自 Epoch 以来以纳秒为单位)
- 字符串:它正在等待的文本原因
- uvarint:当前正在运行帧的上下文指针
- uvarint:操作系统线程描述符的地址 (M)
- uvarint:顶部 defer 记录
- uvarint:顶部 panic 记录
可能的状态
- 0 = 空闲
- 1 = 可运行
- 3 = 系统调用
- 4 = 等待
在所有情况下都必须有等待字段,但只有在状态为“等待”时它们才有意义。
堆栈帧
- uvarint:堆栈指针(帧中的最低地址)
- uvarint:堆栈深度(0 = 堆栈顶部)
- uvarint:子帧的堆栈指针(如果没有则为 0)
- 字符串:堆栈帧的内容
- uvarint:函数的入口 pc
- uvarint:函数的当前 pc
- uvarint:函数的延续 pc(如果在任何地方,函数可能从哪里恢复)
- 字符串:函数名称
- fieldlist:此帧中包含指针的字段的类型和偏移量的列表
转储参数
- 布尔值:大端
- uvarint:以字节为单位的指针大小
- uvarint:以字节为单位的通道头大小
- uvarint:堆的起始地址
- uvarint:堆的结束地址
- uvarint:thechar = 架构说明符
- 字符串:GOEXPERIMENT 环境变量值
- uvarint:runtime.ncpu
终结器
- uvarint:具有终结器的对象的地址
- uvarint:指向描述终结器的 FuncVal 的指针
- uvarint:终结器入口点的 PC
- uvarint:终结器参数的类型
- uvarint:对象的类型
此终结器已在运行时系统中注册,但它引用的对象在最近的 GC 中可达,或在最近的 GC 之后分配。
itab
- uvarint:Itab 地址
- 布尔值:具有此 itab 的 Iface 的数据字段是否为指针
操作系统线程 (M)
- uvarint:此操作系统线程描述符的地址
- uvarint:线程的 Go 内部 ID
- uvarint:操作系统为线程分配的 ID
memstats
转储 MemStats 的前 26 个字段。所有字段均使用 uvarint 转储,除了第 25 个字段,它使用 256 个 uvarint 转储。
queuedfinalizer
- uvarint:具有终结器的对象的地址
- uvarint:指向描述终结器的 FuncVal 的指针
- uvarint:终结器入口点的 PC
- uvarint:终结器参数的类型
- uvarint:对象的类型
此终结器已准备好运行 - 它引用的对象不可达。运行时系统只是还没有运行它。
data
- uvarint:数据段起始地址
- string:数据段的内容
- fieldlist:数据段中包含指针的字段的类型和偏移量。
bss
格式与 data 相同,但适用于 bss 段。
defer
- uvarint:defer 记录地址
- uvarint:包含 goroutine
- uvarint:argp
- uvarint:pc
- uvarint:defer 的 FuncVal
- uvarint:defer 入口点的 PC
- uvarint:指向下一个 defer 记录的链接
panic
- uvarint:panic 记录地址
- uvarint:包含 goroutine
- uvarint:panic 参数 eface 的类型指针
- uvarint:panic 参数 eface 的数据字段
- uvarint:指向当前正在运行的 defer 记录的指针
- uvarint:指向下一个 panic 记录的链接
分配/释放概要文件记录
- uvarint:记录标识符
- uvarint:分配对象的尺寸
- uvarint:堆栈帧数。对于每个帧
-
- 字符串:函数名称
-
- string:文件名
-
- uvarint:行号
- uvarint:分配数
- uvarint:释放数
分配样本记录
- uvarint:对象的地址
- uvarint:分配/释放概要文件记录标识符
此内容是 Go Wiki 的一部分。