【问题标题】:How to profile number of goroutines如何分析 goroutines 的数量
【发布时间】:2019-12-12 02:47:13
【问题描述】:

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

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

这告诉我被阻塞了多长时间,而不是运行了多少例程。

【问题讨论】:

标签: go profiling pprof


【解决方案1】:

在浏览器中打开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

【讨论】:

  • 当debug=1时,@后面的地址是什么意思? - ("0x42f223 0x42f2e4 0x40542f 0x404f4b 0x4a0586 0x4600a1")
【解决方案2】:

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

【讨论】:

  • 不回答“有什么方法可以通过 pprof 做到这一点吗?”
【解决方案3】:
  • 如上所述,我们绝对可以使用runtime.NumGoroutine() 来获取当前可能处于运行或等待状态的 goroutine 数量。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 2014-10-22
    • 2021-12-19
    • 2014-08-27
    • 2016-01-23
    • 2011-09-14
    • 1970-01-01
    相关资源
    最近更新 更多