介绍
pprof
是 Go 语言内置的性能分析工具,可以帮助开发者分析 CPU 和内存的使用情况,从而优化代码性能,下面我通过几个示例介绍不同场景下如何通过golang pprof快速定位性能问题
需要安装的相关工具
- 如果要执行web界面,更直观的显示调试信息需要安装graphviz,详细的安装见官网地址graphviz官网地址
brew install graphviz # macos
apt install graphviz # ubuntu
yum install graphviz # centos
# windows 自行下载安装即可 https://gitlab.com/api/v4/projects/4207231/packages/generic/graphviz-releases/12.0.0/windows_10_cmake_Release_graphviz-install-12.0.0-win64.exe
排查CPU占用
示例代码
// 创建示例项目pprof-example/ ├── main.go └── go.mod
package main
import (
"fmt"
"math/rand"
"net/http"
_ "net/http/pprof"
"time"
)
func main() {
go func() {
fmt.Println(http.ListenAndServe("localhost:6060", nil))
}()
for {
work()
}
}
func work() {
data := make([]int, 0)
for i := 0; i < 1000000; i++ {
data = append(data, rand.Intn(100))
}
time.Sleep(1 * time.Second)
}
步骤
- 先运行项目
go run main.go
,程序启动后pprof 服务器将监听在localhost:6060
端口。 - 执行
go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
,这个命令会收集 30 秒的 CPU 使用数据,并启动一个交互式的 pprof 界面。在这个界面中,你可以使用以下命令进行分析:- top: 显示 CPU 使用最多的函数。
- list : 显示特定函数的详细信息。
- web: 生成图形化的调用图(需要安装 Graphviz)。
排查内存占用
示例代码
package main
import (
"fmt"
"math/rand"
"net/http"
_ "net/http/pprof"
"time"
)
func main() {
go func() {
fmt.Println(http.ListenAndServe("localhost:6060", nil))
}()
for {
memoryIntensiveWork()
}
}
func memoryIntensiveWork() {
data := make([][]int, 0)
for i := 0; i < 1000; i++ {
innerData := make([]int, 1000)
for j := range innerData {
innerData[j] = rand.Intn(100)
}
data = append(data, innerData)
}
time.Sleep(1 * time.Second)
}
步骤
- 同样先运行项目
go run main.go
,执行go tool pprof http://localhost:6060/debug/pprof/heap
- 上述命令会收集当前的内存使用数据,并启动一个交互式的 pprof 界面。在这个界面中,你仍然可以使用以下命令进行分析:
- top: 显示内存使用最多的函数。
- list : 显示特定函数的详细信息。
- web: 生成图形化的调用图(需要安装 Graphviz)。
Goroutine 分析
示例代码
package main
import (
"fmt"
"net/http"
_ "net/http/pprof"
"time"
)
func main() {
go func() {
fmt.Println(http.ListenAndServe("localhost:6060", nil))
}()
for i := 0; i < 10; i++ {
go goroutineWork()
}
select {} // 阻塞主 Goroutine
}
func goroutineWork() {
for {
fmt.Println("Goroutine working")
time.Sleep(1 * time.Second)
}
}
步骤
- 同样先运行项目
go run main.go
,执行go tool pprof http://localhost:6060/debug/pprof/goroutine
- 同样是下方三个命令排查:
- top: 显示内存使用最多的函数。
- list : 显示特定函数的详细信息。
- web: 生成图形化的调用图(需要安装 Graphviz)。
内存申请相关分析
命令
go tool pprof http://localhost:6060/debug/pprof/allocs
- 仍然是三步大法, top、list、web