Go探查器的输出令人困惑(且不正确?)

我正在尝试分析Go二进制文件,并且得到了令人惊讶的结果。该代码的中有以下(被截断的)main.go代码,其余代码在软件包中monte:


package main


import (

  "monte"

  "runtime/pprof"

)


var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")


func main() {

  flag.Parse()

  if *cpuprofile != "" {

    f, err := os.Create(*cpuprofile)

    if err != nil {

      log.Fatal(err)

    }

    pprof.StartCPUProfile(f)

  }


  monte.ExpensiveOperation()


  pprof.StopCPUProfile()

}

我用构建我的可执行文件go build src/main.go,然后用运行它./main -cpuprofile=monte.prof。当我使用检查输出时go tool pprof main monte.prof,得到以下输出:


(pprof) top10 --cum

Total: 346 samples

     280  80.9%  80.9%      343  99.1% time.Time.Format

       0   0.0%  80.9%      341  98.6% runtime.interhash

       0   0.0%  80.9%      341  98.6% runtime.main

       0   0.0%  80.9%      251  72.5% strconv.Unquote

      13   3.8%  84.7%       31   9.0% strconv.roundShortest

      11   3.2%  87.9%       18   5.2% strconv.fmtE

       9   2.6%  90.5%        9   2.6% runtime.markallocated

       1   0.3%  90.8%        8   2.3% math/rand.Float64

       2   0.6%  91.3%        8   2.3% runtime.FixAlloc_Free

       7   2.0%  93.4%        8   2.3% time.nextStdChunk

具有最大累积时间的函数是time.Time.Format,这对我来说似乎是错误的(应该不是main吗?)monte,尽管“昂贵的操作”大约需要10秒钟才能完成,但没有任何提及让采样器看到它。如果我将--focus=monte标志传递给go tool pprof,则根本不会显示任何示例。我认为我在某处缺少一些标志;有人有什么想法吗?谢谢!


潇湘沐
浏览 210回答 2
2回答

元芳怎么了

它看起来像是仅用于CPU的探查器,因此,如果您ExpensiveOperation花费大量时间进行I / O或睡眠或类似操作,则它将不可见。(这就是“ cpu”分析器的问题。)就数字的含义而言,看起来总共有346个样本。根据配置程序的工作方式,这些数字有点糊涂也就不足为奇了,但是如果它是一个真正的堆栈采样器,那么这些数字就意味着:341/346个样品具有main和interhash。您可能希望所有样本都在堆栈上,但是那是黏糊糊的部分。Format堆栈上有343/346个样本。(为什么其中的main数目比谁知道的还要多?)Unquote堆栈上有251/346个样本。因此,这些样品251的,它们也可能有main,interhash和Format堆栈。通过这种侦探工作,您可以慢慢地整理出样本告诉您的内容。当然,如果您实际上可以看到堆栈样本,则不必先查看其中的很多样本,就可以确切知道发生了什么。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go