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
更合适,特别当您想要查找您的程序在哪个独立的功能上花费了大部分时间。