Go本身自带的工具链就包含了性能分析工具,pprof就是Go性能分析的利器,它是Go语言自带的包,有如下两种:
有三种方法:
package main
import (
"fmt"
"net/http"
_ "net/http/pprof"
)
func main() {
go func() {
for {
do("hello,world")
}
}()
fmt.Println("启动服务器...")
err := http.ListenAndServe(":8080", nil)
if err != nil {
panic(err)
}
}
func do(s string) {
s1 := make([]string, 0)
for i := 0; i < 100; i++ {
s1 = append(s1, s)
}
}
启动上面代码后,访问 http://localhost:8080/debug/pprof/ ,就可以看到监控页面了
名词解释:
go tool pprof
启动上述代码后,再运行此命令
//这个命令的作用是追踪上面代码60秒内CPU的消耗情况
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=60
执行该命令后,需等待 60 秒(可调整 seconds 的值),pprof 会进行 CPU Profiling。结束后将默认进入 pprof 的交互式命令模式,可以对分析的结果进行查看或导出。具体可执行 pprof help 查看命令说明
go tool pprof http://localhost:8080/debug/pprof/heap
3.同步原语阻塞的堆栈跟踪
go tool pprof http://localhost:6060/debug/pprof/block
4.互斥锁持有者的堆栈跟踪
go tool pprof http://localhost:6060/debug/pprof/mutex
5.收集 5 秒内的执行路径
go tool pprof http://localhost:6060/debug/pprof/trace?seconds=5
1.编写测试用例
package data
import "testing"
const url = "https://github.com/EDDYCJY"
func TestAdd(t *testing.T) {
s := Add(url)
if s == "" {
t.Errorf("Test.Add error!")
}
}
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
Add(url)
}
}
2.执行
go test -bench=. -cpuprofile=cpu.prof //分析CPU
go test -bench=. -memprofile=memory.prof //分析内存
参数解释:
3.启动可视化界面
方法1
go tool pprof -http=:6060 cpu.prof //CPU
//go tool pprof -http=:6060 memory.prof //内存
方法2(不建议用)
go tool pprof cpu.prof
//go tool pprof memory.prof
(pprof) web
如果出现错误 Could not execute dot; may need to install graphviz.,就需要装 graphviz
-VIEW 看各种视图
- Top:类似于 linux top 那种形式。从高到底排序
- Graph:主要看调用关系图,并且通过框框的粗细、颜色当深浅、线的实虚、 以及数字信息包括执行时间和占比
- Flame Graph:火焰图,要看宽度和深度,heap 中宽度表明内存占用大小,
- Peek 类似于 Top 也是从高到底的排序。
- Source 和交互命令式的那种一样,带有源码标注。
- Disassemble 显示所有的总量。
- SAMPLE:采样信息,包括申请对象、申请空间、占用对象、占用空间的信息
- REFINE:主要是依据右边的 Search regexp 输入框对 SAMPLE 做一些结果筛选分析
- Focus:聚焦在选中元素的上下游元素
- Ignore:忽略选中当元素,包含其后继元素
- Hide:隐藏选中当元素,但不会隐藏其后继元素
- Show:只显示选中的元素,不包含后继元素
- Show from:从选中当某一个元素开始,只列出其后继元素
- CONFIG:能将当前已精细化的页面保存起来
火焰图是基于 perf 结果产生的 SVG 图片,用来展示 CPU 的调用栈。
Y轴表示调用栈,每一层都是一个函数,调用栈越深火焰就越高,最底部是正在执行的函数,上面是它的父函数。
X轴表示这个函数的抽样数,如果一个函数在X轴占的越宽,代表抽样数越高,执行CPU的时间越长,注意,X轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。
火焰图就是看顶层的哪个函数占据的宽度最大。只要有"平顶"(plateaus),就表示该函数可能存在性能问题