go trace不用于函数耗时分析,只记录goroutine调度、gc、系统调用等运行时事件;需用os.create创建文件传给trace.start并确保trace.stop执行,再通过go tool trace -http=:8080解析。

Go 的 trace 文件不能直接“读”,必须用 go tool trace 解析;它不展示函数耗时,只反映 goroutine 状态变迁、调度延迟、GC 触发点等运行时行为——想定位哪行代码慢,该看 pprof,不是 trace。
trace.out 为什么打开后显示 “No traces found”
90% 是文件本身无效,不是浏览器或命令写错。常见原因:
-
trace.Stop()没执行:比如os.Exit(0)、panic()或log.Fatal()会跳过defer,导致文件末尾损坏,go tool trace报EOF或unknown magic number - 程序运行时间太短:默认采样间隔约 10ms,若主逻辑秒级退出(如纯计算 +
select{}),可能只录到ProcStart和GCStart,没实质调度事件 -
trace.Start()调得太晚:比如放在http.ListenAndServe()之后,服务一启就卡住,后续无机会写入 - 文件被截断或混入日志:别用
os.Stdout或log.Writer()接trace.Start(),二进制数据+文本会解析失败
如何确保生成可解析的 trace.out
最小可靠写法,重点在“留出采集窗口”和“避免 defer 失效”:
- 显式创建文件:
f, _ := os.Create("trace.out"),传*os.File给trace.Start(f),不能传路径字符串 -
trace.Stop()必须执行:推荐写在业务逻辑之后、time.Sleep之前,不依赖defer在main返回时才触发(可能已来不及写完) - 强制留出采集时间:
time.Sleep(200 * time.Millisecond)是最简单有效的方式;若用select{},得配time.After,否则调度器无事可做 - 避免在
init()中调trace.Start():此时 runtime 尚未初始化,静默失败,无任何提示
View trace 页面里关键视图怎么看
浏览器打开 go tool trace -http=:8080 trace.out 后,核心面板不是火焰图,而是运行时状态流:
-
View trace:横向时间轴,每行是一个 P(逻辑处理器),能看到 goroutine 在不同 P 上的迁移、阻塞类型(chan send/netpoll/syscall)、GC STW 阶段 -
Goroutine analysis:列出所有 goroutine,点击可看其生命周期:何时创建、在哪阻塞、何时被唤醒、是否被抢占 -
Scheduler latency profile:直方图,显示 goroutine 从就绪到真正运行的延迟分布;若大量落在 10ms+,说明 P 不足或存在长时阻塞 -
Synchronization blocking profile:识别 channel、mutex、waitgroup 等同步原语的阻塞热点,但不告诉你哪行代码,只告诉你哪个 goroutine 卡在哪类操作上
为什么看不到函数名和源码行号
go tool trace 本身不记录函数调用栈,它只记录运行时事件(如 GoroutineReady、GoBlockSend、GCStart)。这些事件由 runtime 内部 hook 注入,不经过编译期符号表。
这意味着:
- 你无法在
View trace中点击某段灰色块看到对应main.go:42 -
User defined tasks/regions是唯一能关联业务逻辑的方式,需手动用trace.WithRegion或trace.Log打点 - 若真要对齐函数耗时,必须同时采集
pprof.Profile(如runtime/pprof.StartCPUProfile),再靠时间戳粗略比对
最容易被忽略的一点:trace 和 pprof 是互补工具,不是替代关系;用错场景,比如拿 trace 查 HTTP handler 响应时间,只会陷入无意义的 goroutine 状态切换中。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











