一.pprof
- Profiling 是指在程序執行過程中,收集能夠反映程序執行狀態的數據。在軟件工程中,性能分析(performance analysis,也稱為 profiling),是以收集程序運行時信息為手段研究程序行為的分析方法,是一種動態程序分析的方法。
- GO中自帶兩個庫可以進行程序分析調優:
1)runtime/pprof 對於本地只跑一次的程序,例如程序中的某一函數調優,調用 pprof 包提供的函數,手動開啟性能數據采集。
2)net/http/pprof 對於在線服務,對於一個 HTTP Server,訪問 pprof 提供的 HTTP 接口,獲得性能數據。當然,實際上這里底層也是調用的 runtime/pprof 提供的函數,封裝成接口對外提供網絡訪問。
一般常用net/http/pprof,操作相對簡單
包含的性能數據

- allocs 和 heap 采樣的信息一致,不過前者是所有對象的內存分配,而 heap 則是活躍對象的內存分配
二.net/http/pprof 使用
1)導包,啟動端口服務
//只需要在你的程序中加入以下幾行代碼
import _ "net/http/pprof"
func maim() {
go func() {
http.ListenAndServe("0.0.0.0:8686", nil)
}()
}
原理
在初始化導包的時候,pprof 包會自動注冊 handler,即我們調試過程中查看的接口:
func init() {
http.Handle("/debug/pprof/", http.HandlerFunc(Index))
http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline))
http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile))
http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol))
http.Handle("/debug/pprof/trace", http.HandlerFunc(Trace))
}
2)服務啟動后,可以瀏覽器訪問
http://127.0.0.1:8686/debug/pprof/
由於網頁般數據可讀性較差,服務器終端一般用命令行讀取數據
# 下載 cpu profile,
go tool pprof http://47.93.238.9:8080/debug/pprof/profile
# 默認手機30S的數據,通過seconds調整時間120s
go tool pprof http://47.93.238.9:8080/debug/pprof/profile?seconds=120
# 下載 heap profile
go tool pprof http://47.93.238.9:8080/debug/pprof/heap
# 下載 goroutine profile
go tool pprof http://47.93.238.9:8080/debug/pprof/goroutine
# 下載 block profile
go tool pprof http://47.93.238.9:8080/debug/pprof/block
# 下載 mutex profile
go tool pprof http://47.93.238.9:8080/debug/pprof/mutex
3)輸入上述命令后,會打開終端交互界面,交互常用命令 top、 list、 traces、 web
- top

獲取前20條,cpu占用的函數
flat--- 該函數占時
flat% --- 該函數相對於總耗時的百分比
sum% --- 前面累計每一行flat 占比
cum --- 該函數以及該函數調用的其他函數總耗時
cum --- 對應的百分比
- list 具體函數: 如結合上圖 list Eat 直接定位到消耗資源的代碼處
- traces 列出函數的調用棧
實戰中,首先通過profile,定位cpu消耗暫時較大的函數,然后通過heap定位內存占用較大的函數邏輯。
通過pprof定位性能瓶頸,根據實際問題優化,從而實現性能的提高
三.內存泄漏查找
內存分配既可以發生在堆上也可以在棧上。堆上分配的內存需要垃圾回收或者手動回收(對於沒有垃圾回收的語言,例如 C++),棧上的內存則通常在函數退出后自動釋放。
什么是內存泄漏
內存泄漏是指程序運行過程中已不再使用的內存,沒有被釋放,導致這些內存一直無法使用,直到程序結束這些內存才被釋放的問題
一般形成主要有兩個原因:
- goroutine 的阻塞
- GC回收時,無法實現100%的回收
怎么發現內存泄露
1、監控工具: 固定周期對進程內存占用采樣,數據可視化后,根據內存占用走勢(持續上升)
- 雲平台的監控工具,或者建立一個腳本,定時執行采集數據
2、go pprof 間隔一段時間采集文件,對比分析是否存在明顯的增量
對比heap
1)通過 go tool pprof http://47.93.238.9:8080/debug/pprof/heap 命令,在間隔一段時間后,分別獲取兩個文件;
2)go tool pprof -base file1 file2 對比兩個文件,top獲取對比后占用增加明顯的函數塊
對比goroutine
1)通過 go tool pprof http://47.93.238.9:8080/debug/pprof/goroutine命令,在間隔一段時間后,分別獲取兩個文件;
2)go tool pprof -base file1 file2 對比兩個文件,top獲取對比后占用增加明顯的函數塊
