pprof工具原理来自于在Scala Days 2011上Robert Hundt发表的一篇名为 Loop Recognition in C++/Java/Go/Scala.的论文。这篇论文实现了一种特定的循环查找算法,例如您可以在C ++,Go,Java,Scala中使用编译器的流分析传递,然后使用这些程序得出这些语言中典型性能问题的结论。该论文中提出的Go程序运行速度非常慢,这使它成为演示如何使用Go的分析工具来实现慢速程序并使其更快的绝佳机会。
web程序
在main.go中加入如下代码:
import (
"log"
"net/http"
_ "net/http/pprof"
)
func main() {
go func() {
log.Println(http.ListenAndServe(":8061", nil))
}()
// ... Other codes
}
_ "net/http/pprof"
这行代码很重要,需要手动加上,否则也无法在浏览器查看。启动成功后,可在浏览器输入网址:http://localhost:8061/debug/pprof
关键名词解释(Profile)
- profile(cpu profiling),默认进行 30s 的 CPU Profiling,得到一个分析用的 profile 文件
- block,查看导致阻塞同步的堆栈跟踪
- goroutine, 查看当前所有运行的 goroutines 堆栈跟踪
- heap(Memory Profiling),查看活动对象的内存分配情况
- mutex(Mutex Profiling),查看导致互斥锁的竞争持有者的堆栈跟踪
- threadcreate,查看创建新OS线程的堆栈跟踪
分析
火焰图
go tool pprof --http=":8081" [binary] [profile]
如:go tool pprof --http=":8081" bdms mem-32057.memprof
cpu
centos命令行窗口输入:go tool pprof http://localhost:8061/debug/pprof/profile,30s后进入交互式界面:
你也可以指定cpu的监测时间,加入seconds参数: go tool pprof http://localhost:8061/debug/pprof/profile?seconds=60
top
输入top查看占用cpu前10的函数,也可指定top数,如top25
启用CPU分析时,Go程序每秒停止大约100次,并在当前正在执行的goroutine堆栈上记录由程序计数器组成的样本。
- flat:给定函数上运行耗时
- flat%:占整个 CPU 运行耗时总比例
- sum%:给定函数累积使用 CPU 总比例
- cum:当前函数加上它之上的调用运行总耗时
- cum%:占整个 CPU 运行耗时总比例
- 最后一列是函数名
要按第四和第五列排序,请使用-cum(for cumulative)标志:
web
堆栈跟踪示例包含有关函数调用关系的有趣数据,而不是文本列表可以显示的数据。该web
命令以SVG格式写入配置文件数据的图形,并在Web浏览器中打开它。(还有一个gv
命令可以编写PostScript并在Ghostview中打开它。对于任一命令,您需要安装graphviz)。或者sudo yum install graphviz
on CentOS。
(pprof) web
我们可以看到该程序将大部分时间都花在某个函数操作上,这时可以告诉web只使用包含特定功能的样本,例如bccsp来清除一些噪音。
(pprof) web bccsp
现在我们已经大致了解了大局,现在是时候放大一个特定的功能了。让我们先看一下(*SharedDataController).Upload,因为它是一个较短的功能:
(pprof) list Upload
列表显示了该Upload函数的源代码(实际上,是对于与正则表达式匹配Upload的每个函数)。第一行是采集的总体花费时间,前三列是运行该行或从该行调用的代码中采集的时间,以及文件中的行号。