Go Wiki: heapdump15-through-heapdump17
其他版本的堆转储格式
- Go 1.3: heapdump13
- Go 1.4: heapdump14
引言
Go 1.5 包含一个 `runtime/debug.WriteHeapDump` 函数,可以将堆中的所有对象以及额外信息(roots、goroutines、finalizers 等)写入文件。该文件的格式在此处指定。
详细信息
文件以字符串“go1.5 heap dump\n”的字节开头。此描述也适用于以“go1.6 heap dump\n”和“go1.7 heap dump\n”开头的文件。go1.6 格式与 1.5 相同,go1.7 格式有一个小改动,如下所述。
文件的其余部分是一系列记录。记录可以有几种不同的类型。记录将包含以下基本类型:
- uvarint - 一个 64 位无符号整数,编码方式与 `encoding/binary` 中的 `Put/ReadUvarint` 相同
- string - 一个 uvarint 编码的长度,后跟该长度的字节数据
- bool - 一个 uvarint 编码的 0(表示 false)或 1(表示 true)
- fieldlist - 描述内存区域中包含指针的部分。它由重复的 uvarint 对组成,编码字段类型和字段偏移量,然后是一个列表结束标记。唯一可能的类型是 1=Ptr。早期版本的堆转储可能包含 2=Iface 和 3=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:对象的地址
- string:对象的内容
- fieldlist: 描述对象中包含指针的字段
contents 字符串的大小是包含它的 sizeclass 的大小,而不是对象本身的大小。因此,contents 的大小可能比所包含对象类型的大小稍大。
otherroot
- string:此根的来源的文本描述
- uvarint:根指针
type
- uvarint:类型描述符的地址
- uvarint:此类型对象的尺寸
- string:类型名称
- bool: 包含此类型的值的接口的数据字段是类型 T(false)还是 *T(true)
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:堆的结束地址
- string: 架构名称
- string:GOEXPERIMENT 环境变量的值
- uvarint:`runtime.ncpu`
finalizer
- uvarint:具有 finalizer 的对象的地址
- uvarint:指向描述 finalizer 的 `FuncVal` 的指针
- uvarint:finalizer 入口点的 PC
- uvarint:finalizer 参数的类型
- uvarint:对象的类型
此 finalizer 已注册到运行时系统,但它引用的对象在最近一次 GC 时是可达的,或者是在最近一次 GC 之后分配的。
itab
- uvarint:Itab 地址
- uvarint: 所包含类型的类型描述符的地址
- 在 go1.6 之前,类型始终是指针类型,并表示 itab.data 字段的类型。
- 从 go1.7 开始,类型是存储在接口中的类型。要确定 itab.data 字段是 T 还是 *T,需要查看所引用类型的描述符中的最后一个布尔值。
osthread (M)
- uvarint:此操作系统线程描述符的地址
- uvarint:线程的 Go 内部 ID
- uvarint:操作系统线程的 ID
memstats
记录 runtime.MemStats 的以下字段
- uvarint: Alloc
- uvarint: TotalAlloc
- uvarint: Sys
- uvarint: Lookups
- uvarint: Mallocs
- uvarint: Frees
- uvarint: HeapAlloc
- uvarint: HeapSys
- uvarint: HeapIdle
- uvarint: HeapInuse
- uvarint: HeapReleased
- uvarint: HeapObjects
- uvarint: StackInuse
- uvarint: StackSys
- uvarint: MSpanInuse
- uvarint: MSpanSys
- uvarint: MCacheInuse
- uvarint: MCacheSys
- uvarint: BuckHashSys
- uvarint: GCSys
- uvarint: OtherSys
- uvarint: NextGC
- uvarint: LastGC
- uvarint: PauseTotalNs
- 256 个 uvarint: PauseNs
- uvarint: NumGC
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 的一部分。