go tool的代码追踪

go tool trace 实用程序是一个工具,用来查看由以下三种方式中任何一种产生的追踪文件:

  • 使用 runtime/trace
  • 使用 net/http/pprof
  • 执行 go test --trace 命令

这节将只使用第一种技术。如下命令的输出将极大帮助您理解 Go execution tracer 在做什么:

第2章(深入剖析Go的内部原理),我们讨论了 Go 的垃圾回收,并介绍了一个 Go 实用程序 gColl.go,它能让我们看到 Go 垃圾回收的一些变量。在这节,我将使用 go tool trace 实用程序来获得关于 goColl.go 操作的更多信息。

首先,让我们来查看一下 gColl.go 程序的修改版,它告诉 Go 去收集性能数据。它被另存为 goGC.go,将分三部分来介绍。

goGC.go 的第一部分如下:

package main
import (
    "fmt"
    "os"
    "runtime"
    "runtime/trace"
    "time"
)
func printStats(mem runtime.MemStats) {
    runtime.ReadMemStats(&mem)
    fmt.Println("mem.Alloc:", mem.Alloc)
    fmt.Println("mem.TotalAlloc:", mem.TotalAlloc)
    fmt.Println("mem.HeapAlloc:", mem.HeapAlloc)
    fmt.Println("-----")
} 

如您所知,您首先需要引入 runtime/trace 标准包以便为 go tool trace 实用程序收集数据。

goGC.go 的第二段代码如下:

func main() {
    f, err := os.Create("/tmp/traceFile.out")
    if err != nil {
        panic(err)
    }
    defer f.Close()
    err = trace.Start(f)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer trace.Stop()

这部分是所有为 go tool trace 实用程序获取数据的地方,并且它与实际程序的功能无关。首先,你将创建一个新文件来保存为 go tool trace 工具追踪的数据。然后,您使用 trace.Start() 启动追踪处理。当您完成追踪,可以调用 trace.Stop() 函数。defer 调用这个函数的意思是您想要在程序结束时终止追踪。

使用 go tool trace 实用程序是一个包含俩个需要额外 Go 代码阶段的过程。首先您收集数据,然后您显示并处理数据。

余下代码如下:

    var mem runtime.MemStats
    printStats(mem)
    for i := 0; i < 3; i++ {
        s := make([]byte, 50000000)
        if s == nil {
            fmt.Println("Operation failed!")
        }
    }
    printStats(mem)
    for i := 0; i < 5; i++ {
        s := make([]byte, 100000000)
        if s == nil {
            fmt.Println("Operation failed!")
        }
        time.Sleep(time.Millisecond)
    }
    printStats(mem)
}

执行 goGC.go 产生如下输出以及带有跟踪信息的名为 /tmp/traceFile.out 的新文件:

$ go run goGC.go
mem.Alloc: 107264
mem.TotalAlloc: 107264
mem.HeapAlloc: 107264
mem.NumGC: 0
-----
mem.Alloc: 50117672
mem.TotalAlloc: 150129416
mem.HeapAlloc: 50117672
mem.NumGC: 3
-----
mem.Alloc: 117320
mem.TotalAlloc: 650174208
mem.HeapAlloc: 117320
mem.NumGC: 8
-----
$ cd /tmp
$ ls -l traceFile.out
-rw-r--r-- 1 mtsouk wheel 8275 Mar 7 08:37 traceFile.out
$ file /tmp/traceFile.out
/tmp/traceFile.out: data

当您执行如下命令时,go tool trace 实用程序自动开启一个web 节目:

$ go tool trace /tmp/traceFile.out
2018/03/07 08:34:36 Parsing trace...
2018/03/07 08:34:36 Serializing trace...
2018/03/07 08:34:36 Splitting trace...
2018/03/07 08:34:36 Opening browser. Trace viewer is listening on http://127.0.0.1:61428

下面的截屏显示了当查看 tmp/traceFiel.out 追踪文件时,go tool trace 实用程序的初始 web 界面:

现在您应该选择 View trace 链接。它将带您到下个界面,显示 go tool trace 实用程序的另一个 web 界面,使用来自 /tmp/traceFile.out 的数据:

从上图,您能看到 Go GC 运行在自己的 goroutine,但它没有一直运行。另外,您可以看到程序使用了一定数量的 goroutines。关于Go GC,您可以通过选择交互界面的某些部分来了解更多信息。由于我们对 GC 的操作感兴趣,一段有用的显示信息是 Go GC 运行的频率和持续时间。

注意尽管 go tool trace 是一个非常方便强大的工具,但它不能解决任何性能问题。有时 go tool pprof 更合适,特别当您想要查找您的程序在哪个独立的功能上花费了大部分时间。

最后编辑: kuteng  文档更新时间: 2021-03-27 20:14   作者:kuteng