Go GC Trace 输出格式详解

4 阅读3分钟

为k8s pod 增加golang 程序gc trace:

env:
- name: GODEBUG
  value: "gctrace=1,scavtrace=1"

Go GC Trace 输出格式详解

以这条为例:

gc 14 @165.909s 0%: 0.045+0.79+0.028 ms clock, 0.36+0.32/1.4/2.3+0.22 ms cpu, 4063->4191->2147 MB, 4355 MB goal, 0 MB stacks, 0 MB globals, 8 P

第一段:基本信息

gc 14 @165.909s 0%
字段示例值含义
gc 1414这是程序启动以来的第 14 次 GC
@165.909s165.909程序启动后 165.909 秒触发
0%0从程序启动到现在,GC 累计占用的 CPU 时间百分比

第二段:Wall Clock 时间(实际经过时间)

0.045+0.79+0.028 ms clock

GC 分为三个阶段,对应三个数值:

阶段示例值说明
STW Sweep Termination0.045 ms第一次 Stop-The-World:暂停所有 goroutine,结束上一轮的清扫工作,准备开始标记
Concurrent Mark & Scan0.79 ms并发阶段:标记所有可达对象。此阶段与应用 goroutine 同时运行,不暂停程序
STW Mark Termination0.028 ms第二次 Stop-The-World:暂停所有 goroutine,完成标记,启动清扫

💡 真正影响延迟的是第 1 和第 3 个值(STW 暂停) ,你的数据中均 < 0.2ms,非常优秀。


第三段:CPU 时间(所有核心累计)

0.36+0.32/1.4/2.3+0.22 ms cpu
字段示例值含义
STW Sweep Termination CPU0.36 ms第一次 STW 在所有 P 上消耗的 CPU 总时间
Assist(辅助标记)0.32 ms分配内存的 goroutine 被迫帮忙做标记的 CPU 时间
Dedicated(专用 GC 线程)1.4 ms专门用于 GC 标记的后台 goroutine 的 CPU 时间
Idle(空闲窃取)2.3 ms空闲 P 偷过来做 GC 标记的 CPU 时间
STW Mark Termination CPU0.22 ms第二次 STW 在所有 P 上消耗的 CPU 总时间
格式:STW1 + assist/dedicated/idle + STW2

💡 Assist 高意味着分配压力大——分配速度太快,GC 来不及标记,迫使分配者"交税"帮忙做标记。你的 assist 值很低(0.32ms),说明没有压力。


第四段:堆内存变化(最重要 ⭐)

4063->4191->2147 MB
字段示例值含义
GC 开始时堆大小4063 MB触发 GC 时的堆使用量(包含可达 + 不可达对象)
GC 结束时堆大小4191 MBGC 标记阶段结束时堆大小(因为并发标记期间,应用仍在分配新对象,所以可能比开始时更大)
存活对象大小2147 MB标记完成后,仍然可达的对象总大小。这是最关键的指标
回收量 = GC 结束时堆大小 - 存活对象 = 4191 - 2147 = 2044 MB

第五段:GC 目标

4355 MB goal
字段示例值含义
Goal4355 MB下次触发 GC 的堆大小阈值。当堆增长到这个值时触发下次 GC

Goal 的计算公式(默认 GOGC=100):

goal ≈ 存活对象 × (1 + GOGC/100)
     = 2147 × 2
     = ~4294 MB(实际会有 runtime 的微调)

第六段:栈和全局变量

0 MB stacks, 0 MB globals
字段示例值含义
Stacks0 MB所有 goroutine 使用的内存(向上取整到 MB,小于 1MB 显示为 0)
Globals0 MB全局变量(包含 BSS 段等)扫描的内存量

Go 1.22+ 开始输出这两个字段,帮助判断非堆内存的占用。


第七段:处理器数量

8 P
字段示例值含义
P8Go scheduler 使用的逻辑处理器数量(等于 GOMAXPROCS,默认等于 CPU 核心数)

完整格式模板

gc {次数} @{时间}s {CPU占比}%: {STW1}+{并发标记}+{STW2} ms clock, {STW1_cpu}+{assist}/{dedicated}/{idle}+{STW2_cpu} ms cpu, {GC前堆}->{GC后堆}->{存活} MB, {goal} MB goal, {stacks} MB stacks, {globals} MB globals, {P} P

快速看问题的优先级

优先级看什么健康标准
⭐⭐⭐存活对象是否持续增长稳定 = 无泄漏,持续增长 = 可能泄漏
⭐⭐STW 暂停时间(第1和第3个值)< 1ms 优秀,> 10ms 需关注
GC CPU 占比< 5% 正常,> 25% 需优化
Assist 时间接近 0 最好,过高说明分配压力大