Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
137 lines (104 sloc) 4.74 KB

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 界面:

go trace tool 的初始 web 界面

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

使用 go tool trace 查看 Go 垃圾收集的操作

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

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

You can’t perform that action at this time.