假设下面的代码是你要分析的 Go 代码:
package mainimport ("fmt""sync""time"
)// 模拟耗时操作
func hardWork(wg *sync.WaitGroup) {defer wg.Done()fmt.Printf("Start: %v\n", time.Now())// 模拟耗内存a := []string{}for i := 0; i < 500000; i++ {a = append(a, "aaaa")}// 模拟阻塞操作time.Sleep(2 * time.Second)fmt.Printf("End: %v\n", time.Now())
}func main() {// 启动一个协程来执行 hardWork,并且等待它执行完成var wg sync.WaitGroupwg.Add(1)go hardWork(&wg)wg.Wait()
}
现在我们通过 pprof 来对其进行分析,我们需要做如下步骤:
- 安装
graphviz
,这可以让我们以图形的形式来展示分析结果。mac 下通过brew install graphviz
来安装,windows 下的安装可以自行在 csdn 搜索一下 - 安装 pprof:
go get -u github.com/google/pprof
- 在 Go 代码中添加导入:
import _ "net/http/pprof"
- 添加 pprof 的 web 端口:
go func() {fmt.Println(http.ListenAndServe("localhost:6060", nil))
}()
最终代码是下面这样的:
package mainimport ("fmt""net/http""sync""time"_ "net/http/pprof"
)// 模拟耗时操作
func hardWork(wg *sync.WaitGroup) {defer wg.Done()fmt.Printf("Start: %v\n", time.Now())// 模拟耗内存a := []string{}for i := 0; i < 500000; i++ {a = append(a, "aaaa")}// 模拟阻塞操作time.Sleep(2 * time.Second)fmt.Printf("End: %v\n", time.Now())
}func main() {var wg sync.WaitGroup// pprof 分析结果的界面go func() {fmt.Println(http.ListenAndServe("localhost:6060", nil))}()// 启动一个协程来执行 hardWork,并且等待它执行完成wg.Add(1) // 等待 pprof 协程wg.Add(1) // 等待 hardWork 完成go hardWork(&wg)wg.Wait()
}
接着,我们在控制台执行下面的命令:
go tool pprof http://localhost:6060/debug/pprof/heap
我们会进入一个交互式的命令行:
Fetching profile over HTTP from http://localhost:6060/debug/pprof/heap
Saved profile in /Users/ruby/pprof/pprof.alloc_objects.alloc_space.inuse_objects.inuse_space.001.pb.gz
Type: inuse_space
Time: Jan 11, 2024 at 10:21am (CST)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) // 我们可以在这里输入不同的命令
接着,我们在这个交互式的命令行中输入 png
,它就会在我们项目的根目录下生成了一个分析结果的图片(注意:需要安装 graphviz
):
另一种查看分析结果的方式
当然,命令行这种方式还是不太方便,我们可以直接打开浏览器访问:
http://localhost:6060/debug/pprof/
在这个页面,我们只需要通过鼠标点击就可以看到不同的性能指标了:
在这里,我们可以很容易查看我们的 Go 程序的一些性能指标,比如:
- 内存
- 协程
- 阻塞
- 锁