GoLand不直接标记协程泄漏,但可通过正确配置pprof(如import _ "net/http/pprof"、监听127.0.0.1:6060)、在Run→Edit Configurations中启用Goroutines profiling,并利用Filter by Stack Trace筛选chan receive/select等阻塞点来快速定位泄漏源。

GoLand 本身不标记“协程泄漏”,但能帮你快速定位阻塞、堆积、未退出的 goroutine——关键在正确启动 pprof 并过滤可疑调用点。
必须先让服务暴露 /debug/pprof/goroutine
GoLand 不采集数据,它只发请求;真正提供数据的是你代码里注册的 pprof handler。
-
import _ "net/http/pprof"必须是下划线导入,否则 handler 不挂载 - 启动 HTTP server 时第二个参数传
nil,确保标准路由(包括/debug/pprof/*)自动生效:http.ListenAndServe("127.0.0.1:6060", nil) - 别用
"0.0.0.0:6060",本地调试优先用"127.0.0.1:6060",避免 hostname 解析失败或端口被占 - 用
curl -v http://127.0.0.1:6060/debug/pprof/goroutine?debug=2验证:返回纯文本堆栈才算成功;404 或空响应说明没挂上
GoLand 启动 profiling 要选对类型
默认点击 Run → Start Profiling 是 CPU 分析,根本不会拉 goroutine 数据。
GoLand 2026.1.1 是 2026.1 发布后的首个维护修正版本,适合已经开始体验 2026.1 新功能并希望同步补丁的开发者。它更适合用于入门项目、现有项目迁移测试和 IDE 行为验证。
- 必须进
Run → Edit Configurations…,勾选Enable profiling,再从下拉菜单明确选Goroutines - 端口要和代码里
ListenAndServe的一致,比如你代码监听127.0.0.1:6060,这里就不能填6061 - 如果用了
dlv启动、自定义构建脚本或容器运行,GoLand 的 profiling 注入大概率失效——此时直接用命令行:go tool pprof http://localhost:6060/debug/pprof/goroutine?debug=2
在 Profiler 界面识别泄漏信号
协程泄漏最常见表现不是数量多,而是长期卡在某个阻塞点不动。GoLand 的火焰图和堆栈列表能帮你聚焦这些位置。
- Profiler 界面生成 goroutine 列表后,右键任意节点 →
Filter by Stack Trace→ 输入chan receive或select,立刻高亮所有阻塞在 channel 上的协程 - 双击火焰图中某帧,GoLand 自动跳转到源码行——重点关注
go func() { ... }()、time.AfterFunc、ch 这类调用,它们常是泄漏源头 - 注意
runtime.gopark出现的位置:若大量 goroutine 停在semacquire(锁)、chanrecv(channel recv)或selectgo,说明没被唤醒或没被关闭
别依赖 GoLand 自动判断是否泄漏
它不会告诉你“这个 goroutine 泄漏了”,也不会比对两次快照的差值。是否泄漏,得靠你结合业务逻辑做判断。
- 压测前记一次
runtime.NumGoroutine(),压测后等 30 秒再查——如果比空闲态高 300+ 且不回落,基本可确认泄漏已固化 -
/debug/pprof/goroutine?debug=2返回的堆栈里,反复出现同一段闭包调用(比如func·001)且状态始终是chan receive,大概率是 channel 没 close 或 sender 挂了 - 全局 map 插入后没删、
context.WithCancel后没调cancel()、time.Ticker启动后忘了Stop()——这些代码编译期完全合法,GoLand 静态检查器根本不会报
真正决定是否泄漏的,是你对调用链的理解,而不是 GoLand 是否标红了某一行。它只是把 /debug/pprof/goroutine?debug=2 的结果整理得更易读,把火焰图点击跳转做得更快——剩下的事,得你来干。

















