goland 不支持 threadcreate profile 可视化,需手动调用 go tool pprof 访问 /debug/pprof/threadcreate 接口(如 http://localhost:6060/debug/pprof/threadcreate?seconds=30),前提是程序已启用 net/http/pprof 且有真实 os 线程创建事件。

GoLand 里直接看不了 threadcreate,得靠命令行采样
GoLand 本身不提供 threadcreate profile 的可视化界面,它没有集成 go tool pprof 对线程创建事件的解析逻辑。你点开内置的 “Profiler” 工具(Run → Start Profiling)看到的是 CPU / Memory 的采样,跟 /debug/pprof/threadcreate 完全无关。
要查 threadcreate,必须手动触发 HTTP 接口 + go tool pprof
前提是你的 Go 程序已启用 net/http/pprof 并监听了端口(比如 :6060),且显式开启了线程创建追踪——Go 默认不记录 threadcreate,它只在有 OS 线程被新建时才捕获堆栈,但需要服务端配合:
-
import _ "net/http/pprof"(下划线导入,触发 init 注册路由) - 确保
http.ListenAndServe(":6060", nil)或等效 mux 挂载了/debug/pprof/路径 -
threadcreate不需要额外调用runtime函数开启,只要程序确实创建了新 OS 线程(比如大量 goroutine 阻塞后 runtime 启动新 M),它就会有数据
然后在终端执行:
GoLand 2026.1.1 是 2026.1 发布后的首个维护修正版本,适合已经开始体验 2026.1 新功能并希望同步补丁的开发者。它更适合用于入门项目、现有项目迁移测试和 IDE 行为验证。
go tool pprof http://localhost:6060/debug/pprof/threadcreate?seconds=30
注意:?seconds=30 是必须的,否则默认返回最近一次采样(可能为空);threadcreate 是瞬时事件,不是持续流,所以得靠时间窗口抓取。
GoLand 中能做的辅助动作只有这三步
虽然不能直接渲染,但你可以让 GoLand 帮你省掉手动切终端的麻烦:
- 在 Run Configuration → Environment Variables 里加
GODEBUG=schedtrace=1000(可选,辅助观察调度器是否频繁启 M) - 在 Run Configuration → Go Tool Arguments 里填
-gcflags="all=-l" -ldflags="-s -w"(避免内联干扰堆栈,方便pprof定位源头) - 用 GoLand 的 “Terminal” 标签页,粘贴并运行上面那条
go tool pprof命令,它会自动打开浏览器到http://127.0.0.1:8080(或你指定的地址)查看火焰图和调用树
容易漏掉的关键点:threadcreate 数据稀疏且依赖真实负载
threadcreate profile 不像 profile 或 heap 那样稳定产出数据。它只在 runtime 创建新 OS 线程时记录一次堆栈,而现代 Go 应用极少主动创建线程——绝大多数情况是 goroutine 长时间阻塞(如 syscalls、cgo、锁竞争)导致 runtime 被迫拉起新 M。所以:
- 压测时如果没看到
threadcreate数据,大概率说明没触发真正阻塞,而不是工具没配对 - 若想强制触发,可在代码中模拟一个长时间阻塞调用,例如
syscall.Read(0, buf)(需 importsyscall)或启动大量同步 I/O goroutine -
go tool pprof解析出的调用栈顶层往往是runtime.newm或runtime.startTheWorldWithSema,真正业务代码藏在倒数第二三级,别只盯着顶层看










