pprof是golang自带的性能分析工具,在程序运行过程中,可以记录程序的运行信息,像CPU使用情况、内存使用情况、协程的情况等等。
pprof主要有两种使用方式:
下面给出一个简单的示例程序(例子摘自网上):
package main
import (
"log"
"math/rand"
"os"
"runtime/pprof"
"time"
)
const (
row = 1000
col = 1000
)
func fillMatrix(m *[row][col]int) {
s := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < row; i++ {
for j := 0; j < col; j++ {
m[i][j] = s.Intn(100000)
}
}
}
func main() {
//创建输出文件
f, err := os.Create("cpu.prof")
if err != nil {
log.Fatal("could not create CPU profile: ", err)
}
//获取系统信息
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatal("could not start cpu profile: ", err)
}
defer pprof.StopCPUProfile()
//待分析代码
x := [row][col]int{}
fillMatrix(&x)
f1, err := os.Create("mem.prof")
if err != nil {
log.Fatal("could not create memory profile: ", err)
}
//获取堆内存占用情况
if err := pprof.WriteHeapProfile(f1); err != nil {
log.Fatal("could not write memory profile: ", err)
}
f1.Close()
//获取协程情况
f2, err := os.Create("goroutine.prof")
if err != nil {
log.Fatal("could not create goroutine profile: ", err)
}
if gProf := pprof.Lookup("goroutine"); gProf == nil {
log.Fatal("could not write goroutine profile")
} else {
gProf.WriteTo(f2, 0)
}
f2.Close()
}
文件名:pprof_try.go
在文件所在目录下执行:go build pprof_try.go
目录下会出现pprof_try可执行文件:./pprof_try
此时就会生成三个相应的prof文件:cpu.prof、mem.prof、goroutine.prof
这里以cpu.prof文件为例:
执行go tool pprof pprof_try cpu.prof,会进入交互模式:
Type: cpu
Time: Jul 25, 2020 at 12:07am (CST)
Duration: 206.15ms, Total samples = 10ms ( 4.85%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof)
交互模式有很多可使用的命令(可以使用help查看简介),比较常用的是top、list、traces三个
Type: cpu
Time: Jul 25, 2020 at 12:07am (CST)
Duration: 206.15ms, Total samples = 10ms ( 4.85%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 10ms, 100% of 10ms total
flat flat% sum% cum cum%
10ms 100% 100% 10ms 100% main.fillMatrix
0 0% 100% 10ms 100% main.main
0 0% 100% 10ms 100% runtime.main
(pprof)
top命令展示函数的5个数据:
list可以具体查看某个函数的每行代码以及每行代码的相应指标,函数名支持模糊匹配:
Type: cpu
Time: Jul 25, 2020 at 12:07am (CST)
Duration: 206.15ms, Total samples = 10ms ( 4.85%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 10ms, 100% of 10ms total
flat flat% sum% cum cum%
10ms 100% 100% 10ms 100% main.fillMatrix
0 0% 100% 10ms 100% main.main
0 0% 100% 10ms 100% runtime.main
(pprof) list fillMatrix
Total: 10ms
ROUTINE ======================== main.fillMatrix in /Users/lcj/go_pro/src/aboutGo/pproftest/pprof_try.go
10ms 10ms (flat, cum) 100% of Total
. . 23:
. . 24:func fillMatrix(m *[row][col]int) {
. . 25: s := rand.New(rand.NewSource(time.Now().UnixNano()))
. . 26:
. . 27: for i := 0; i < row; i++ {
10ms 10ms 28: for j := 0; j < col; j++ {
. . 29: m[i][j] = s.Intn(100000)
. . 30: }
. . 31: }
. . 32:}
. . 33:
(pprof)
traces命令可以打印所有调用栈和相应的指标信息:
File: pprof_try
Type: cpu
Time: Jul 25, 2020 at 12:07am (CST)
Duration: 206.15ms, Total samples = 10ms ( 4.85%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) traces
File: pprof_try
Type: cpu
Time: Jul 25, 2020 at 12:07am (CST)
Duration: 206.15ms, Total samples = 10ms ( 4.85%)
-----------+-------------------------------------------------------
10ms main.fillMatrix
main.main
runtime.main
-----------+-------------------------------------------------------
(pprof)
还有svg指令,可以将调用过程生成一个svg图,可以在浏览器进行直观查看。
如果安装了go-torch,还可以使用go-torch cpu.prof生成火炬图进行查看。
分析服务器上运行的程序性能,需要使用这种方式。
在程序中导入以下包,并启动http server即可。
improt _ "net/http/pprof"
实例代码(示例摘自网上):
package main
import (
"fmt"
"log"
"net/http"
_ "net/http/pprof"
)
func GetFbSeries(n int) []int {
res := make([]int, 2, n)
res[0] = 1
res[1] = 1
for i := 2; i < n; i++ {
res = append(res, res[i-1]+res[i-2])
}
return res
}
func createFBS(w http.ResponseWriter, r *http.Request) {
var fbs []int
for i := 0; i < 1000000; i++ {
fbs = GetFbSeries(50)
}
w.Write([]byte(fmt.Sprintf("%v", fbs)))
}
func main() {
http.HandleFunc("/fb", createFBS)
log.Fatal(http.ListenAndServe(":8080", nil))
}
可以直接通过网页查看:
http://{host:port}/debug/pprof/
也可以在本地通过命令行查看:
go tool pprof http://{host:port}/debug/pprof/profile?seconds=10
seconds参数表述表示采样时间,默认是30s
url中的profile表示cpu,其它类目可以通过上述网页看到
如果安装了go-torch命令,可以使用以下命令生成火炬图:
go-torch -seconds 10 http://{host:port}/debug/pprof/profile
url中的profile表示cpu,其它类目可以通过上述网页看到
进行内存状况分析时,有以下两个参数可以使用:
**如:**go tool pprof -inuse_space http://{host:port}/debug/pprof/profile