Go Wiki:heapdump13
其他版本的堆转储格式
- Go 1.4:heapdump14
- Go 1.5 及更高版本:heapdump15-through-heapdump17
引言
Go 1.3 添加了 `runtime/debug.WriteHeapDump` 函数,该函数将堆中的所有对象以及其他信息(根、goroutine、finalizer 等)写入文件。该文件的格式在此处指定。
详细信息
文件以字符串“go1.3 heap dump\n”的字节开头。
文件的其余部分是一系列记录。记录可以有几种不同的类型。记录将包含以下基本类型:
- uvarint - 一个 64 位无符号整数,编码方式与 `encoding/binary` 中的 `Put/ReadUvarint` 相同
- 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 = object(对象)
- 2 = otherroot(其他根)
- 3 = type(类型)
- 4 = goroutine(goroutine)
- 5 = stack frame(堆栈帧)
- 6 = dump params(转储参数)
- 7 = registered finalizer(已注册的 finalizer)
- 8 = itab(接口表)
- 9 = OS thread(操作系统线程)
- 10 = mem stats(内存统计)
- 11 = queued finalizer(已排队的 finalizer)
- 12 = data segment(数据段)
- 13 = bss segment(bss 段)
- 14 = defer record(defer 记录)
- 15 = panic record(panic 记录)
- 16 = alloc/free profile record(分配/释放剖析记录)
- 17 = alloc stack trace sample(分配堆栈跟踪样本)
每条记录的其余字段取决于类型,并在下面进行描述。
EOF
EOF 记录没有字段,并且必须出现在最后。
object
- uvarint:对象的地址
- uvarint:类型描述符的地址(如果未知则为 0)
- uvarint:对象的类型(0=regular(常规)、1=array(数组)、2=channel(通道)、127=conservatively scanned(保守扫描))
- string:对象的内容
对于数组或通道类型,类型必须是非零的。
内容字符串的大小是包含它的 sizeclass 的大小,而不是类型本身的大小。因此,内容大小可能比类型大小稍大。对于数组和通道类型,它可能大得多。例如,一个包含 n 个元素的数组的内容大小将大于或等于 n 乘以类型大小。
otherroot
- string:此根的来源的文本描述
- uvarint:根指针
type
- uvarint:类型描述符的地址
- uvarint:此类型对象的尺寸
- string:类型名称
- bool:包含此类型值的接口的 `data` 字段是否是指针
- fieldlist:一个包含此类型对象中包含指针的字段的类型和位置的列表
goroutine (G)
- uvarint:描述符的地址
- uvarint:堆栈顶部(当前运行的帧,又名深度 0)的指针
- uvarint:goroutine ID
- uvarint:创建此 goroutine 的 `go` 语句的位置
- uvarint:状态
- bool:是否为系统启动的 goroutine
- bool:是否为后台 goroutine
- uvarint:goroutine 上次开始等待的大约时间(自纪元以来的纳秒)
- string:它正在等待的文本原因
- uvarint:当前运行帧的上下文指针
- uvarint:操作系统线程描述符 (M) 的地址
- uvarint:顶部 defer 记录
- uvarint:顶部 panic 记录
可能的状态
- 0 = idle(空闲)
- 1 = runnable(可运行)
- 3 = syscall(系统调用)
- 4 = waiting(等待)
在所有情况下都必须存在等待字段,但只有当状态为“waiting”时它们才有意义。
stack frame
- uvarint:堆栈指针(帧中最低的地址)
- uvarint:堆栈中的深度(0 = 堆栈顶部)
- uvarint:子帧的堆栈指针(无则为 0)
- string:堆栈帧的内容
- uvarint:函数的入口 PC
- uvarint:函数的当前 PC
- uvarint:函数的 continuation PC(函数可以恢复的地方,如果可能的话)
- string:函数名称
- fieldlist:此帧中包含指针的字段的类型和偏移量列表
dump params
- bool:大端序
- uvarint:指针大小(字节)
- uvarint:通道头大小(字节)
- uvarint:堆的起始地址
- uvarint:堆的结束地址
- uvarint:`thechar` = 架构说明符
- string:GOEXPERIMENT 环境变量的值
- uvarint:`runtime.ncpu`
finalizer
- uvarint:具有 finalizer 的对象的地址
- uvarint:指向描述 finalizer 的 `FuncVal` 的指针
- uvarint:finalizer 入口点的 PC
- uvarint:finalizer 参数的类型
- uvarint:对象的类型
此 finalizer 已注册到运行时系统,但它引用的对象在最近一次 GC 时是可达的,或者是在最近一次 GC 之后分配的。
itab
- uvarint:Itab 地址
- bool:具有此 itab 的 Iface 的 `data` 字段是否是指针
osthread (M)
- uvarint:此操作系统线程描述符的地址
- uvarint:线程的 Go 内部 ID
- uvarint:操作系统线程的 ID
memstats
转储 `runtime.MemStats` 的前 26 个字段。所有字段都使用 uvarint 存储,除了第 25 个字段,它使用 256 个 uvarint 存储。
queuedfinalizer
- uvarint:具有 finalizer 的对象的地址
- uvarint:指向描述 finalizer 的 `FuncVal` 的指针
- uvarint:finalizer 入口点的 PC
- uvarint:finalizer 参数的类型
- uvarint:对象的类型
此 finalizer 已准备好运行——它引用的对象是不可达的。运行时系统尚未开始运行它。
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 的 data 字段
- uvarint:指向当前正在运行的 defer 记录的指针
- uvarint:指向下一个 panic 记录的链接
alloc/free profile record
- uvarint:记录标识符
- uvarint:已分配对象的尺寸
- uvarint:堆栈帧的数量。对于每个帧
-
- string:函数名称
-
- string:文件名
-
- uvarint:行号
- uvarint:分配数量
- uvarint:释放数量
alloc sample record
- uvarint:对象的地址
- uvarint:alloc/free profile record 标识符
此内容是 Go Wiki 的一部分。