You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go Trace中“GC Pause”的含义及用户Goroutine暂停疑问

关于Go Trace中“GC Pause”列的疑问解答

问题描述

我用Go trace追踪函数执行时间,程序里创建了大量对象,疑惑GC暂停时间是不是太长。查看源码发现,“GC Pause”列用的是GCTime字段,对应GCDone事件,但GCSTW、GCSweep是独立事件,看起来GCTime是总GC时间而非STW(暂停)时间。想请教:“GC Pause”列具体指什么?这段时间内用户goroutine会被暂停吗?

相关源码分析

cmd/trace/goroutines.go#L298

<table class="details">
<tr>
<th onclick="reloadTable('sortby', 'SweepTime')" class="sweep-time"> GC sweeping</th>
<th onclick="reloadTable('sortby', 'GCTime')" class="pause-time"> GC pause</th>
</tr>
{{range .GList}}
  <tr>
    <td> {{prettyDuration .SweepTime}} {{percent .SweepTime .TotalTime}}</td>
    <td> {{prettyDuration .GCTime}} {{percent .GCTime .TotalTime}}</td>
  </tr>
{{end}}
</table>

internal/trace/goroutines.go#L275

const (
    EvGCStart           = 7  // GC start [timestamp, seq, stack id]
    EvGCDone            = 8  // GC done [timestamp]
    EvSTWStart          = 9  // GC mark termination start [timestamp, kind]
    EvSTWDone           = 10 // GC mark termination done [timestamp]
    EvGCSweepStart      = 11 // GC sweep start [timestamp, stack id]
    EvGCSweepDone       = 12 // GC sweep done [timestamp, swept, reclaimed]
)

func GoroutineStats() {
    // ...

    case EvGCStart:
        gcStartTime = ev.Ts
    case EvGCDone:
        for _, g := range gs {
            if g.EndTime != 0 {
                continue
            }
            if gcStartTime < g.CreationTime {
                g.GCTime += ev.Ts - g.CreationTime
            } else {
                g.GCTime += ev.Ts - gcStartTime
            }
        }
        gcStartTime = 0 // indicates gc is inactive.
}

测试环境与命令

$ go version
go version go1.21.0 darwin/amd64

$ go test -bench=BenchmarkGoTrace -benchtime=1000x -run=NONE -trace=trace.out
cpu: Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
BenchmarkGoTrace-8          1000      22500692 ns/op

$ go tool trace trace.out

解答

  1. “GC Pause”列的实际含义
    从源码的计算逻辑来看,GCTime统计的是整个GC周期的总时长:从EvGCStart(GC启动)到EvGCDone(GC完全结束)的全部时间,包含了标记阶段(并发执行+短暂STW)、清扫阶段(大部分并发执行)的所有耗时。这个列名存在一定误导性,它并非指用户goroutine被暂停的STW时间。

  2. 用户goroutine的暂停情况
    Go的GC是并发设计,整个GC周期内只有两个短暂的STW(Stop The World)阶段会暂停所有用户goroutine:

    • GC启动初期的栈扫描准备阶段
    • 标记终止阶段(确保标记结果的一致性)
      而GCTime包含的大部分时间里,用户goroutine都可以正常运行,不会被暂停。

内容的提问来源于stack exchange,提问作者F566

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 20:55:28