- 前言
- Go 与操作系统
- Go 内部机制
- Go 基本数据类型
- 4 组合类型的使用
- 5 数据结构
- 6 Go package 中不为人知的知识
- 7 反射和接口
- 8 Go UNIX 系统编程
- 08.1 关于 UNIX 进程
- 08.2 flag 包
- 8.2 flag 包
- 08.3 io.Reader 和 io.Writer 接口
- 08.4 bufio 包
- 08.5 读取文本文件
- 08.6 从文件中读取所需的数据量
- 08.7 为什么我们使用二进制格式
- 08.8 读取 CSV 文件
- 08.9 写入文件
- 08.10 从磁盘加载和保存数据
- 08.11 再看strings包
- 08.12 关于bytes包
- 08.13 文件权限
- 08.14 处理 Unix 信号
- 08.15 Unix 管道编程
- 08.16 遍历目录树
- 08.17 使用 ePBF
- 08.18 关于 syscall.PtraceRegs
- 08.19 跟踪系统调用
- 08.20 User ID 和 group ID
- 08.21 其他资源
- 08.22 练习
- 08.23 总结
- 9 并发 Goroutines、Channel 和 Pipeline
- 10 Go 并发-进阶讨论
- 11 代码测试、优化及分析
- 12 Go 网络编程基础
- 13 网络编程 - 构建服务器与客户端
11.6 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
更合适,特别当您想要查找您的程序在哪个独立的功能上花费了大部分时间。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论