3

基本上我想知道我的程序是否会随着时间的推移泄漏 goroutines。所以我想看看随着时间的推移有多少 goroutines 正在运行。有什么办法可以做到这一点pprof吗?

我已经完成了go tool pprof http://localhost:8888/debug/pprof/block

这给了我被阻塞了多长时间,而不是有多少例程正在运行。

4

3 回答 3

15

在浏览器中打开http://localhost:8888/debug/pprof/ 。你会看到两个相关的链接:“goroutine”(http://localhost:8888/debug/pprof/goroutine?debug=1)和“full goroutine stack dump”(http://localhost:8888/debug/pprof/ goroutine?debug=2)。

第一个将显示与一个条目共享相同代码的所有 goroutine,在其名称前显示此类 goroutine 的数量。例如:

1 @ 0x42f223 0x42f2e4 0x40542f 0x404f4b 0x4a0586 0x4600a1
#   0x4a0586    gitlab.com/gitlab-org/gitlab-ci-multi-runner/commands.(*RunCommand).startWorkers+0x56   /home/me/go/src/gitlab.com/gitlab-org/gitlab-ci-multi-runner/commands/multi.go:164

1 @ 0x42f223 0x43dfd7 0x43d532 0x4a04ed 0x4600a1
#   0x4a04ed    gitlab.com/gitlab-org/gitlab-ci-multi-runner/commands.(*RunCommand).processRunners+0x45d    /home/me/go/src/gitlab.com/gitlab-org/gitlab-ci-multi-runner/commands/multi.go:147

这两个 goroutine 都有一个,这就是 @ 之前的 1 的意思。

完整转储对于查找泄漏非常有用,它会分别向您显示每个 goroutine,以及它的堆栈跟踪和它在做什么(例如,它等待从通道接收多长时间):

goroutine 49 [chan receive, 2 minutes]:
gitlab.com/gitlab-org/gitlab-ci-multi-runner/commands.(*RunCommand).startWorkers(0xc820103ee0, 0xc820274000, 0xc820274060, 0xc8201d65a0)
    /home/me/go/src/gitlab.com/gitlab-org/gitlab-ci-multi-runner/commands/multi.go:164 +0x56
created by gitlab.com/gitlab-org/gitlab-ci-multi-runner/commands.(*RunCommand).Run
    /home/me/go/src/gitlab.com/gitlab-org/gitlab-ci-multi-runner/commands/multi.go:294 +0x41b

goroutine 50 [select]:
gitlab.com/gitlab-org/gitlab-ci-multi-runner/commands.(*RunCommand).processRunners(0xc820103ee0, 0x0, 0xc820274060, 0xc8201d65a0)
    /home/me/go/src/gitlab.com/gitlab-org/gitlab-ci-multi-runner/commands/multi.go:147 +0x45d
created by gitlab.com/gitlab-org/gitlab-ci-multi-runner/commands.(*RunCommand).startWorkers
    /home/me/go/src/gitlab.com/gitlab-org/gitlab-ci-multi-runner/commands/multi.go:165 +0x96
于 2016-07-16T18:53:51.253 回答
1

正如 icza 指出的那样,答案是使用runtime.NumGoroutine().

于 2016-07-15T18:44:20.163 回答
0
  • 如上所述,我们绝对可以使用runtime.NumGoroutine()来获取可能处于运行或等待状态的 goroutines 的当前数量。

  • 我们可以使用Lookup函数来获取一些配置文件。它们可以是预定义的配置文件,如 goroutine、堆、allocs、互斥锁等,也可以是自定义配置文件。更多在这里

  • 我们可以链接WriteTo定义的方法Profile来写入标准输出或文件。例子pprof.Lookup("goroutine").WriteTo(writer, 2)
  • 这将为您提供有关每个 go-routine 的重要详细信息,例如等待的时间、等待的时间、是否在睡觉等。
  • 您可以使用该信息指出真正的问题所在。
于 2019-12-11T18:47:13.310 回答