Go1.5正式版程序性能分析小積累,實驗環境windows64
方法一:
內存分配器跟蹤:GODEBUG=allocfreetrace=1
調度器追蹤
調度器追蹤能夠提供對 goroutine 調度的動態行為的內視,而且同意調試負載平衡和可擴展性問題。要啟用調度器追蹤。
能夠帶有環境變量 GODEBUG=schedtrace=1000 來執行程序(這個值的意思是輸入的周期,單位 ms,這樣的情況下是每秒一次):
set GODEBUG=schedtrace=1000
SCHED 1004ms: gomaxprocs=4 idleprocs=0 threads=11 idlethreads=4 runqueue=8 [0 1 0 3] SCHED 2005ms: gomaxprocs=4 idleprocs=0 threads=11 idlethreads=5 runqueue=6 [1 5 4 0] SCHED 3008ms: gomaxprocs=4 idleprocs=0 threads=11 idlethreads=4 runqueue=10 [2 2 2 1]
第一個數字("1004ms")是從程序開始後的時間。Gomaxprocs 是當前的 GOMAXPROCS 值。 Idleprocs 是空載的處理器數(剩下的在執行 Go 代碼)。Threads 是調度器產生的工作線程總數(線程有三種狀態:執行 Go 代碼(gomaxprocs-idleprocs),執行 syscalls/cgocalls。閑置)。
Idlethreads是閑置的工作線程數。
Runqueue 是執行的 goroutine 的全局隊列長度。方括號裏的數字("[0 1 0 3]")是可執行的 goroutine 的預處理器隊列的長度。
全局和局部隊列的長度總和表示執行中可用的 goroutine 的總數。 註意:你能夠任意組合追蹤器。如:GODEBUG = gctrace = 1,allocfreetrace = 1,schedtrace = 1000。 註意:相同有具體的調度器追蹤,你能夠這樣啟用它:GODEBUG = schedtrace = 1000,scheddetail = 1。它將會輸出每個 goroutine、工作線程和處理器的具體信息。我們將不會在這裏討論它的格式,由於它主要是給調度器開發人員使用;你能夠在這裏src/pkg/runtime/proc.c找到它的具體信息。 當一個程序不與 GOMAXPROCS 成線性比例和/或沒有消耗 100% 的 CPU 時間,調度器追蹤就顯得很實用。理想的情況是:全部的處理器都在忙碌地執行 Go 代碼,線程數合理。全部隊列都有充足的任務且任務是合理均勻的分布的: gomaxprocs=8 idleprocs=0 threads=40 idlethreads=5 runqueue=10 [20 20 20 20 20 20 20 20] 不好的情況是上面所列的東西並沒有全然達到。比如以下這個演示,沒有足夠的任務來保持全部的處理器繁忙: gomaxprocs=8 idleprocs=6 threads=40 idlethreads=30 runqueue=0 [0 2 0 0 0 1 0 0] 註意:這裏使用操作系統提供的實際CPU利用率作為終於的標準。在 Unix 系操作系統中是 top 命令。在 Windows 系統中是任務管理器。 你能夠使用 goroutine 分析器來了解哪些 goroutine 塊處於任務短缺狀態。
註意,僅僅要全部的處理器處於忙綠狀態,負載失衡就不是最壞的,它僅僅會導致適度的負載平衡開銷。
內存統計 Go 執行時能夠通過 runtime.ReadMemStats 函數提供粗糙的內存統計。這個統計相同能夠通過 http://myserver:6060/debug/pprof/heap?
debug=1 底部的net/http/pprof提供。統計資料,點擊此處。 一些值得關註的地方是: 1. HeapAlloc - 當前堆大小。 2. HeapSys - 總的堆大小。 3. HeapObjects - 堆中對象的總數。
4. HeapReleased - 釋放到操作系統中的內存。假設內存超過五分鐘沒有使用,執行時將會把它釋放到操作系統中,你能夠通過 runtime/debug.FreeOSMemory 來強制改變這個過程。
5. Sys - 操作系統分配的總內存。 6. Sys-HeapReleased - 程序的有效內存消耗。
7. StackSys - goroutine 棧的內存消耗(註意:一些棧是從堆中分配的。因此沒有計入這裏。不幸的是,沒有辦法得到棧的總大小(https://code.google.com/p/go/issues/detail?id=7468))。
8. MSpanSys/MCacheSys/BuckHashSys/GCSys/OtherSys - 執行時為各種輔助用途分配的內存;它們沒什麽好關註的,除非過高的話。 9. PauseNs - 最後一次垃圾回收的持續時間。
使用:set GODEBUG=gctrace=1 / GODEBUG=gctrace=2
直接執行可執行文件:server.exe
格式:gc # @#s #%: #+...+# ms clock, #+...+# ms cpu, #->#-># MB, # MB goal, # P
GC # 表示第幾次GC
@#s 表示程序開始多長時間運行的GC
#% 表示程序開始GC時間占用的百分比(percentage of time spent in GC since program start)
#+...+# 表示GC運行時CPU堵塞時間和
#->#-># MB 表示GC開始堆大小,結束堆大小,在活躍堆大小
# MB goal 表示目標對大小
# P 表示程序執行時CPU核數
演示樣例 :
gc 13 @1277.835s 0%: 0+1.0+0+1.0+1.0 ms clock, 0+1.0+0+0/1.0/0+3.0 ms cpu, 0->0->0 MB, 4 MB goal, 4 P
方法二:
import _ "net/http/pprof" go func() { log.Println(http.ListenAndServe("localhost:6060", nil)) }() 在程序中加入以上代碼. ----------------------------------------------------------- 使用以下的命令能夠查看各項性能: go tool pprof http://localhost:6060/debug/pprof/heap 查看30秒內的cpu使用: go tool pprof http://localhost:6060/debug/pprof/profile 查看goroutime性能: go tool pprof http://localhost:6060/debug/pprof/block 查看5秒的執行trace. wget http://localhost:6060/debug/pprof/trace?seconds=5 在瀏覽器打開查看: http://localhost:6060/debug/pprof/ https://blog.golang.org/2011/06/profiling-go-programs.html 命令:go tool pprof /mnt/Go/src/main http://localhost:6060/debug/pprof/heap 輸入list能夠看到具體情況. 輸入web 能夠在web頁面查看 此外我們也能夠執行go tool pprof your-executable-name --dot profile-filename > heap.gv,這樣將得到一個heap.gv文件,我們在graphviz裏面打開這個文件將得到一個更具體的包含調用關系在內的內存消耗圖。當然。我們假設僅僅須要一張圖,也能夠執行dot -Tpng heap.gv > heap.png將這個gv文件另存為png圖,這樣就能夠像我一樣,在以下展示剖析結果了。
三、使用pprof文件分析:
import ( "runtime/pprof" // 引用pprof package "os" ) func main() { f, _ := os.Create("profile_file") pprof.StartCPUProfile(f) // 開始cpu profile,結果寫到文件f中 defer pprof.StopCPUProfile() // 結束profile ... }
執行 執行程序,生成profile文件 分析 在命令行上執行: go tool pprof [binary] [profile] 進入pprof環境後。能夠用help命令查看幫助信息 最經常使用的命令如top10,能夠看最耗時的function 這裏詳解一下top命令的輸出格式。比如: 14 2.1% 17.2% 58 8.7% std::_Rb_tree::find 各字段的含義依次是: 1. 採樣點落在該函數中的次數 2. 採樣點落在該函數中的百分比 3. 上一項的累積百分比 4. 採樣點落在該函數,以及被它調用的函數中的總次數 5. 採樣點落在該函數,以及被它調用的函數中的總次數百分比 6. 函數名
Go1.5正式版程序性能分析小積累,實驗環境windows64