Go Wiki:heapdump13

其他版本的堆转储格式

引言

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 的一部分。