【實踐】WINDOWS下GOlang性能測試分析工具PProf&GO torch入門指導

1.摘要

本文講解在Windows 10操作系統VS Code集成環境下,如何使用GO語言的PProf工具進行性能分析和查看的基本操作,同時也介紹火焰圖呈現GO torch的使用入門指導。

這篇文章比較長,應該是目前PProf&GO torch整理最全的一篇了,把綱要在摘要處先列一下,各位客官各取所需。

2,介紹和環境準備
2.1 PProf介紹
2.2 圖形呈現輔助工具Graphviz
2.3 GO樣例
3,通過WEB運行分析
4. 通過交互式終端分析
4.1 時長爲60s的CPU佔用分析
4.2 heap堆分析
4.3 stack棧分析
4.4 其他
5. PProf 可視化界面
6. go-torch火焰圖生成工具
6.1 安裝go-torch
6.2 下載安裝 Perl ,用於執行 .pl 文件
6.3 生成並分析火焰圖
7. 高性能程序建議
8.參考

2,介紹和環境準備

2.1 PProf介紹

go的pprof工具可以用來監測進程的運行數據,用於監控程序的性能,對內存使用和CPU使用的情況統信息進行分析。
官方提供了兩個包:runtime/pprof和net/http/pprof,前者用於普通代碼的性能分析,後者用於web服務器的性能分析。
PProf不需要獨立安裝,Go環境裝好後即可引用啓動了。

2.1.1 PProf功能

PProf工具可以做以下分析:

  • CPU Profiling:CPU 分析,按照一定的頻率採集所監聽的應用程序 CPU(含寄存器)的使用情況,可確定應用程序在主動消耗 CPU 週期時花費時間的位置;
  • Memory Profiling:內存分析,在應用程序進行堆分配時記錄堆棧跟蹤,用於監視當前和歷史內存使用情況,以及檢查內存泄漏;
  • Block Profiling:阻塞分析,記錄 goroutine 阻塞等待同步(包括定時器通道)的位置;
  • Mutex Profiling:互斥鎖分析,報告互斥鎖的競爭情況;

2.2 圖形呈現輔助工具Graphviz

Graphviz (英文:Graph Visualization Software的縮寫)是一個由AT&T實驗室啓動的開源工具包,用於繪製DOT語言腳本描述的圖形。它也提供了供其它軟件使用的函式庫。
需要圖形化呈現PProf的分析結果,就需要安裝Graphviz工具包。

2.2.1 下載安裝包並安裝

在官網目錄下下載windows的安裝包,並按照默認配置完成安裝。
https://graphviz.gitlab.io/_pages/Download/Download_windows.html

2.2.2 配置環境變量

將graphviz安裝目錄下的bin文件夾添加到Path環境變量中:

C:\Program Files (x86)\Graphviz2.38\bin

操作如下圖:

2.2.3 驗證安裝成功

進入windows命令行界面,輸入顯示版本命令,如果顯示graphviz的相關版本信息,則安裝配置成功。

dot -version

操作如下圖:

2.3 GO樣例

(1) demo.go主程序

位置:$GOPATH\src\pprofDemo\demo.go

package main

import (
    "log"
    "net/http"
    _ "net/http/pprof"
    "pprofDemo/data"
)

func main() {
    go func() {
        for {
            log.Println(data.Add("Hello World"))
        }
    }()

    http.ListenAndServe("0.0.0.0:6060", nil)
}
(2) d.go

位置:$GOPATH\src\pprofDemo\data\demo.go

package data

var datas []string

func Add(str string) string {
    data := []byte(str)
    sData := string(data)
    datas = append(datas, sData)

    return sData
}
(3) 運行GO程序

在Windows的CMD命令行或者VS Code的終端命令行運行程序:

go run demo.go

程序結果:

3,通過WEB運行分析

在瀏覽器下輸入以下地址運行PProf分析:

http://127.0.0.1:6060/debug/pprof/

瀏覽器可呈現以下內容:

/debug/pprof/

Types of profiles available:

| Count | Profile |
| --- | --- |
| 17 | [allocs](http://127.0.0.1:6060/debug/pprof/allocs?debug=1) |
| 0 | [block](http://127.0.0.1:6060/debug/pprof/block?debug=1) |
| 0 | [cmdline](http://127.0.0.1:6060/debug/pprof/cmdline) |
| 5 | [goroutine](http://127.0.0.1:6060/debug/pprof/goroutine?debug=1) |
| 17 | [heap](http://127.0.0.1:6060/debug/pprof/heap?debug=1) |
| 0 | [mutex](http://127.0.0.1:6060/debug/pprof/mutex?debug=1) |
| 0 | [profile](http://127.0.0.1:6060/debug/pprof/profile) |
| 7 | [threadcreate](http://127.0.0.1:6060/debug/pprof/threadcreate?debug=1) |
| 0 | [trace](http://127.0.0.1:6060/debug/pprof/trace) |

[full goroutine stack dump](http://127.0.0.1:6060/debug/pprof/goroutine?debug=2) 

Profile Descriptions:
*   allocs:
     A sampling of all past memory allocations
*   block:
     Stack traces that led to blocking on synchronization primitives
*   cmdline:
     The command line invocation of the current program
*   goroutine:
     Stack traces of all current goroutines
*   heap:
     A sampling of memory allocations of live objects. You can specify the gc GET parameter to run GC before taking the heap sample.
*   mutex:
     Stack traces of holders of contended mutexes
*   profile:
     CPU profile. You can specify the duration in the seconds GET parameter. After you get the profile file, use the go tool pprof command to investigate the profile.
*   threadcreate:
     Stack traces that led to the creation of new OS threads
*   trace:
     A trace of execution of the current program. You can specify the duration in the seconds GET parameter. After you get the trace file, use the go tool trace command to investigate the trace.

【說明】
debug=1時,會將函數地址轉換爲函數名,即脫離 pprof 在瀏覽器中直接查看。
對 goroutine CMD來說,還支持 debug=2,此時將以 unrecovered panic 的格式打印堆棧,可讀性更高。

3.1 alloc - 內存分配情況

點擊第一個鏈接 allocs 可以看到內容分配情況。

http://127.0.0.1:6060/debug/pprof/allocs?debug=1

輸出樣例:

heap profile: 98: 122078816 [707: 334820144] @ heap/1048576
1: 67821568 [1: 67821568] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

1: 54255616 [1: 54255616] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

94: 1504 [94: 1504] @ 0x729c83 0x729c35 0x45cb31
#	0x729c82	pprofDemo/data.Add+0xd2	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:7
#	0x729c34	main.main.func1+0x84	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

2: 128 [386: 24704] @ 0x49c621 0x4c62dd 0x4c5c8c 0x4cbeb7 0x4cbe8a 0x4e4125 0x4e4e13 0x729c34 0x45cb31
#	0x49c620	unicode/utf16.Encode+0x70		C:/Go/src/unicode/utf16/utf16.go:64
#	0x4c62dc	internal/poll.(*FD).writeConsole+0x43c	C:/Go/src/internal/poll/fd_windows.go:732
#	0x4c5c8b	internal/poll.(*FD).Write+0x19b		C:/Go/src/internal/poll/fd_windows.go:676
#	0x4cbeb6	os.(*File).write+0x76			C:/Go/src/os/file_windows.go:224
#	0x4cbe89	os.(*File).Write+0x49			C:/Go/src/os/file.go:145
#	0x4e4124	log.(*Logger).Output+0x204		C:/Go/src/log/log.go:172
#	0x4e4e12	log.Println+0x72			C:/Go/src/log/log.go:308
#	0x729c33	main.main.func1+0x83			D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [0: 0] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 27770880] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 22216704] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 17768448] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 14213120] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 11370496] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 9093120] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 7274496] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 5816320] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 4653056] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 3719168] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 2973696] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 2375680] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 1900544] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 1515520] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [89: 1424] @ 0x729bf6 0x45cb31
#	0x729bf5	main.main.func1+0x45	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 34717696] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 966656] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 770048] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 43401216] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [116: 1856] @ 0x4d5445 0x4e4de6 0x729c34 0x45cb31
#	0x4d5444	fmt.Sprintln+0x84	C:/Go/src/fmt/print.go:283
#	0x4e4de5	log.Println+0x45	C:/Go/src/log/log.go:308
#	0x729c33	main.main.func1+0x83	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 122880] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 73728] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13


# runtime.MemStats
# Alloc = 335946224
# TotalAlloc = 1014013712
# Sys = 473841272
# Lookups = 0
# Mallocs = 21077384
# Frees = 12720394
# HeapAlloc = 335946224
# HeapSys = 448593920
# HeapIdle = 111927296
# HeapInuse = 336666624
# HeapReleased = 111927296
# HeapObjects = 8356990
# Stack = 196608 / 196608
# MSpan = 3232944 / 3260416
# MCache = 6816 / 16384
# BuckHashSys = 1448289
# GCSys = 19006848
# OtherSys = 1318807
# NextGC = 441561264
# LastGC = 1565433417148020100
# PauseNs = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# PauseEnd = [1565433169073748700 1565433170816751000 1565433172159983400 1565433172945533000 1565433174099874000 1565433175518063100 1565433177619860000 1565433179975512400 1565433181864431500 1565433184265065100 1565433187523962900 1565433191149906300 1565433195655882800 1565433202544943300 1565433210091628000 1565433219576071700 1565433231443300400 1565433250042853500 1565433271147866600 1565433296270582800 1565433329182917200 1565433367374672600 1565433417148020100 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# NumGC = 23
# NumForcedGC = 0
# GCCPUFraction = 0.0016365068582352524
# DebugGC = false
3.2 block - 導致阻塞同步的堆棧跟蹤

點擊第二個鏈接 0 | block獲取導致阻塞的 goroutine 堆棧(如 channel, mutex 等)。

http://localhost:6060/debug/pprof/block?debug=1

結果 - 不存在阻塞情況:

--- contention:
cycles/second=2181652749
3.3 cmdline - 當前程序激活的命令行

點擊 0 | cmdline獲得當前程序激活的命令行啓動參數。

http://localhost:6060/debug/pprof/cmdline

結果:

C:\Users\dd\AppData\Local\Temp\go-build574785414\b001\exe\demo.exe
3.4 goroutine - 當前運行的goroutine

點擊 6 | goroutine 獲得當前當前運行的goroutine的堆棧信息。

http://localhost:6060/debug/pprof/goroutine?debug=1

結果:

goroutine profile: total 5
1 @ 0x403e05 0x44ba7d 0x4a4096 0x4c620b 0x4c5c8c 0x4cbeb7 0x4cbe8a 0x4e4125 0x4e4e13 0x729c34 0x45cb31
#	0x44ba7c	syscall.Syscall6+0xec			C:/Go/src/runtime/syscall_windows.go:199
#	0x4a4095	syscall.WriteConsole+0xb5		C:/Go/src/syscall/zsyscall_windows.go:1297
#	0x4c620a	internal/poll.(*FD).writeConsole+0x36a	C:/Go/src/internal/poll/fd_windows.go:735
#	0x4c5c8b	internal/poll.(*FD).Write+0x19b		C:/Go/src/internal/poll/fd_windows.go:676
#	0x4cbeb6	os.(*File).write+0x76			C:/Go/src/os/file_windows.go:224
#	0x4cbe89	os.(*File).Write+0x49			C:/Go/src/os/file.go:145
#	0x4e4124	log.(*Logger).Output+0x204		C:/Go/src/log/log.go:172
#	0x4e4e12	log.Println+0x72			C:/Go/src/log/log.go:308
#	0x729c33	main.main.func1+0x83			D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

1 @ 0x431974 0x42b491 0x42aa0d 0x4c25c2 0x4c38a4 0x4c4edb 0x56f896 0x581e50 0x6938ae 0x61fa16 0x620744 0x62097b 0x623886 0x68dd14 0x68dd06 0x694baa 0x69901f 0x45cb31
#	0x42aa0c	internal/poll.runtime_pollWait+0x5c		C:/Go/src/runtime/netpoll.go:182
#	0x4c25c1	internal/poll.(*pollDesc).wait+0xa1		C:/Go/src/internal/poll/fd_poll_runtime.go:87
#	0x4c38a3	internal/poll.(*ioSrv).ExecIO+0x123		C:/Go/src/internal/poll/fd_windows.go:228
#	0x4c4eda	internal/poll.(*FD).Read+0x26a			C:/Go/src/internal/poll/fd_windows.go:502
#	0x56f895	net.(*netFD).Read+0x55				C:/Go/src/net/fd_windows.go:152
#	0x581e4f	net.(*conn).Read+0x6f				C:/Go/src/net/net.go:177
#	0x6938ad	net/http.(*connReader).Read+0x10d		C:/Go/src/net/http/server.go:787
#	0x61fa15	bufio.(*Reader).fill+0x115			C:/Go/src/bufio/bufio.go:100
#	0x620743	bufio.(*Reader).ReadSlice+0x43			C:/Go/src/bufio/bufio.go:356
#	0x62097a	bufio.(*Reader).ReadLine+0x3a			C:/Go/src/bufio/bufio.go:385
#	0x623885	net/textproto.(*Reader).readLineSlice+0x75	C:/Go/src/net/textproto/reader.go:55
#	0x68dd13	net/textproto.(*Reader).ReadLine+0x93		C:/Go/src/net/textproto/reader.go:36
#	0x68dd05	net/http.readRequest+0x85			C:/Go/src/net/http/request.go:968
#	0x694ba9	net/http.(*conn).readRequest+0x169		C:/Go/src/net/http/server.go:967
#	0x69901e	net/http.(*conn).serve+0x6ae			C:/Go/src/net/http/server.go:1819

1 @ 0x431974 0x42b491 0x42aa0d 0x4c25c2 0x4c38a4 0x4c6fd9 0x4c7278 0x56fe21 0x589bc9 0x58851f 0x69eb66 0x69d9b4 0x69d6eb 0x729b73 0x729b21 0x43157c 0x45cb31
#	0x42aa0c	internal/poll.runtime_pollWait+0x5c		C:/Go/src/runtime/netpoll.go:182
#	0x4c25c1	internal/poll.(*pollDesc).wait+0xa1		C:/Go/src/internal/poll/fd_poll_runtime.go:87
#	0x4c38a3	internal/poll.(*ioSrv).ExecIO+0x123		C:/Go/src/internal/poll/fd_windows.go:228
#	0x4c6fd8	internal/poll.(*FD).acceptOne+0xa8		C:/Go/src/internal/poll/fd_windows.go:862
#	0x4c7277	internal/poll.(*FD).Accept+0x147		C:/Go/src/internal/poll/fd_windows.go:896
#	0x56fe20	net.(*netFD).accept+0x80			C:/Go/src/net/fd_windows.go:193
#	0x589bc8	net.(*TCPListener).accept+0x38			C:/Go/src/net/tcpsock_posix.go:139
#	0x58851e	net.(*TCPListener).AcceptTCP+0x4e		C:/Go/src/net/tcpsock.go:247
#	0x69eb65	net/http.tcpKeepAliveListener.Accept+0x35	C:/Go/src/net/http/server.go:3264
#	0x69d9b3	net/http.(*Server).Serve+0x233			C:/Go/src/net/http/server.go:2859
#	0x69d6ea	net/http.(*Server).ListenAndServe+0xea		C:/Go/src/net/http/server.go:2797
#	0x729b72	net/http.ListenAndServe+0x92			C:/Go/src/net/http/server.go:3037
#	0x729b20	main.main+0x40					D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:17
#	0x43157b	runtime.main+0x20b				C:/Go/src/runtime/proc.go:200

1 @ 0x6933d0 0x45cb31
#	0x6933d0	net/http.(*connReader).backgroundRead+0x0	C:/Go/src/net/http/server.go:676

1 @ 0x71ed87 0x71eb97 0x71b737 0x72874d 0x7291ae 0x69a22b 0x69c13d 0x69d592 0x6991c3 0x45cb31
#	0x71ed86	runtime/pprof.writeRuntimeProfile+0x96	C:/Go/src/runtime/pprof/pprof.go:708
#	0x71eb96	runtime/pprof.writeGoroutine+0xa6	C:/Go/src/runtime/pprof/pprof.go:670
#	0x71b736	runtime/pprof.(*Profile).WriteTo+0x396	C:/Go/src/runtime/pprof/pprof.go:329
#	0x72874c	net/http/pprof.handler.ServeHTTP+0x35c	C:/Go/src/net/http/pprof/pprof.go:245
#	0x7291ad	net/http/pprof.Index+0x6fd		C:/Go/src/net/http/pprof/pprof.go:268
#	0x69a22a	net/http.HandlerFunc.ServeHTTP+0x4a	C:/Go/src/net/http/server.go:1995
#	0x69c13c	net/http.(*ServeMux).ServeHTTP+0x1dc	C:/Go/src/net/http/server.go:2375
#	0x69d591	net/http.serverHandler.ServeHTTP+0xb1	C:/Go/src/net/http/server.go:2774
#	0x6991c2	net/http.(*conn).serve+0x852		C:/Go/src/net/http/server.go:1878
3.5 heap - 存活對象的內存分配情況

點擊 | 23 | heap |
獲得當前當前運行的goroutine跟蹤。

http://localhost:6060/debug/pprof/heap?debug=1

結果:

heap profile: 585: 323462320 [4219: 1613030288] @ heap/1048576
1: 323452928 [1: 323452928] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

583: 9328 [583: 9328] @ 0x729c83 0x729c35 0x45cb31
#	0x729c82	pprofDemo/data.Add+0xd2	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:7
#	0x729c34	main.main.func1+0x84	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

1: 64 [2377: 152128] @ 0x49c621 0x4c62dd 0x4c5c8c 0x4cbeb7 0x4cbe8a 0x4e4125 0x4e4e13 0x729c34 0x45cb31
#	0x49c620	unicode/utf16.Encode+0x70		C:/Go/src/unicode/utf16/utf16.go:64
#	0x4c62dc	internal/poll.(*FD).writeConsole+0x43c	C:/Go/src/internal/poll/fd_windows.go:732
#	0x4c5c8b	internal/poll.(*FD).Write+0x19b		C:/Go/src/internal/poll/fd_windows.go:676
#	0x4cbeb6	os.(*File).write+0x76			C:/Go/src/os/file_windows.go:224
#	0x4cbe89	os.(*File).Write+0x49			C:/Go/src/os/file.go:145
#	0x4e4124	log.(*Logger).Output+0x204		C:/Go/src/log/log.go:172
#	0x4e4e12	log.Println+0x72			C:/Go/src/log/log.go:308
#	0x729c33	main.main.func1+0x83			D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [0: 0] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 165601280] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 132481024] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 105979904] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 84779008] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 67821568] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 54255616] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 43401216] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 34717696] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 27770880] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 22216704] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 17768448] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 14213120] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 11370496] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 9093120] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 7274496] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 5816320] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 4653056] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 3719168] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 2973696] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 2375680] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 1900544] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 1515520] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [617: 9872] @ 0x729bf6 0x45cb31
#	0x729bf5	main.main.func1+0x45	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 207003648] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 966656] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 770048] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 258760704] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [613: 9808] @ 0x4d5445 0x4e4de6 0x729c34 0x45cb31
#	0x4d5444	fmt.Sprintln+0x84	C:/Go/src/fmt/print.go:283
#	0x4e4de5	log.Println+0x45	C:/Go/src/log/log.go:308
#	0x729c33	main.main.func1+0x83	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 122880] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13

0: 0 [1: 73728] @ 0x729d16 0x729c35 0x45cb31
#	0x729d15	pprofDemo/data.Add+0x165	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/data/d.go:8
#	0x729c34	main.main.func1+0x84		D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13


# runtime.MemStats
# Alloc = 903008744
# TotalAlloc = 4550869808
# Sys = 2158105336
# Lookups = 0
# Mallocs = 90329339
# Frees = 63460678
# HeapAlloc = 903008744
# HeapSys = 2063400960
# HeapIdle = 1159651328
# HeapInuse = 903749632
# HeapReleased = 825802752
# HeapObjects = 26868661
# Stack = 196608 / 196608
# MSpan = 8942688 / 9273344
# MCache = 6816 / 16384
# BuckHashSys = 1449689
# GCSys = 81020416
# OtherSys = 2747935
# NextGC = 1487502224
# LastGC = 1565434372301738700
# PauseNs = [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# PauseEnd = [1565433169073748700 1565433170816751000 1565433172159983400 1565433172945533000 1565433174099874000 1565433175518063100 1565433177619860000 1565433179975512400 1565433181864431500 1565433184265065100 1565433187523962900 1565433191149906300 1565433195655882800 1565433202544943300 1565433210091628000 1565433219576071700 1565433231443300400 1565433250042853500 1565433271147866600 1565433296270582800 1565433329182917200 1565433367374672600 1565433417148020100 1565433481563290200 1565433564539085100 1565433658736311100 1565433768426224400 1565433888753832600 1565433950011017300 1565434070459967800 1565434152222298100 1565434272871724400 1565434372301738700 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# NumGC = 33
# NumForcedGC = 0
# GCCPUFraction = 0.0013550620011245496
# DebugGC = false
3.7 mutex - 互斥鎖的競爭持有者的堆棧跟蹤

點擊 | mutex |
導致互斥鎖的競爭持有者的堆棧跟蹤。

http://localhost:6060/debug/pprof/heap?debug=1

結果:

--- mutex:
cycles/second=2181652749
sampling period=0
3.6 profile - 默認進行 30s 的 CPU Profiling

點擊 profile
默認進行 30s 的 CPU Profiling,得到一個分析用的 profile 文件。

http://localhost:6060/debug/pprof/profile

結果:
得到一個分析用的 profile 文件,需要用後面的專用工具分析查看。

3.8 threadcreate - 操作系統線程跟蹤

點擊 | 7 | threadcreate 獲得操作系統線程跟蹤。

http://localhost:6060/debug/pprof/profile

結果:

threadcreate profile: total 8
8 @
#	0x0
3.9 trace - 當前程序執行情況

點擊 | 0 | trace |
獲得當前程序的執行情況,

http://localhost:6060/debug/pprof/trace

結果:
得到一個分析用的 trace 文件,需要用後面的專用工具分析查看。

3.10 full goroutine stack dump - 所有goroutine棧輸出

點擊full goroutine stack dump獲得所有goroutine棧輸出。
結果:

goroutine 27 [running]:
runtime/pprof.writeGoroutineStacks(0x869360, 0xc00829e000, 0x0, 0x0)
	C:/Go/src/runtime/pprof/pprof.go:679 +0xa4
runtime/pprof.writeGoroutine(0x869360, 0xc00829e000, 0x2, 0x40c043, 0xc008282160)
	C:/Go/src/runtime/pprof/pprof.go:668 +0x4b
runtime/pprof.(*Profile).WriteTo(0xae74c0, 0x869360, 0xc00829e000, 0x2, 0xc00829e000, 0xc0000f6000)
	C:/Go/src/runtime/pprof/pprof.go:329 +0x397
net/http/pprof.handler.ServeHTTP(0xc00000a371, 0x9, 0x86f3e0, 0xc00829e000, 0xc0000dc400)
	C:/Go/src/net/http/pprof/pprof.go:245 +0x35d
net/http/pprof.Index(0x86f3e0, 0xc00829e000, 0xc0000dc400)
	C:/Go/src/net/http/pprof/pprof.go:268 +0x6fe
net/http.HandlerFunc.ServeHTTP(0x807588, 0x86f3e0, 0xc00829e000, 0xc0000dc400)
	C:/Go/src/net/http/server.go:1995 +0x4b
net/http.(*ServeMux).ServeHTTP(0xaf4c20, 0x86f3e0, 0xc00829e000, 0xc0000dc400)
	C:/Go/src/net/http/server.go:2375 +0x1dd
net/http.serverHandler.ServeHTTP(0xc0000f41a0, 0x86f3e0, 0xc00829e000, 0xc0000dc400)
	C:/Go/src/net/http/server.go:2774 +0xb2
net/http.(*conn).serve(0xc0000548c0, 0x86fa20, 0xc000038500)
	C:/Go/src/net/http/server.go:1878 +0x853
created by net/http.(*Server).Serve
	C:/Go/src/net/http/server.go:2884 +0x2fb

goroutine 1 [IO wait]:
internal/poll.runtime_pollWait(0x1460ea8, 0x72, 0x869ee0)
	C:/Go/src/runtime/netpoll.go:182 +0x5d
internal/poll.(*pollDesc).wait(0xc0001001c8, 0x72, 0xab8400, 0x0, 0x0)
	C:/Go/src/internal/poll/fd_poll_runtime.go:87 +0xa2
internal/poll.(*ioSrv).ExecIO(0xaf2b90, 0xc000100018, 0xc0000040a0, 0x1, 0x0, 0x170)
	C:/Go/src/internal/poll/fd_windows.go:228 +0x124
internal/poll.(*FD).acceptOne(0xc000100000, 0x170, 0xc00feb60f0, 0x2, 0x2, 0xc000100018, 0xc000008e00, 0xc0003e5c10, 0x40c8ff, 0x10)
	C:/Go/src/internal/poll/fd_windows.go:862 +0xa9
internal/poll.(*FD).Accept(0xc000100000, 0xc003276000, 0x0, 0x0, 0x0, 0x0, 0xc000000000, 0x0, 0x0, 0x0, ...)
	C:/Go/src/internal/poll/fd_windows.go:896 +0x148
net.(*netFD).accept(0xc000100000, 0xc000020570, 0xc000020500, 0x40c043)
	C:/Go/src/net/fd_windows.go:193 +0x81
net.(*TCPListener).accept(0xc000006040, 0xc0003e5dd0, 0xba04deba, 0xbe1590eba5ab90d)
	C:/Go/src/net/tcpsock_posix.go:139 +0x39
net.(*TCPListener).AcceptTCP(0xc000006040, 0xc0000f4230, 0x4b904d, 0x5d4ea46c)
	C:/Go/src/net/tcpsock.go:247 +0x4f
net/http.tcpKeepAliveListener.Accept(0xc000006040, 0xc0003e5e48, 0x18, 0xc00002c000, 0x69da7b)
	C:/Go/src/net/http/server.go:3264 +0x36
net/http.(*Server).Serve(0xc0000f41a0, 0x86f5a0, 0xc000006040, 0x0, 0x0)
	C:/Go/src/net/http/server.go:2859 +0x234
net/http.(*Server).ListenAndServe(0xc0000f41a0, 0xc0000f41a0, 0xc000044058)
	C:/Go/src/net/http/server.go:2797 +0xeb
net/http.ListenAndServe(...)
	C:/Go/src/net/http/server.go:3037
main.main()
	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:17 +0x93

goroutine 4 [runnable, locked to thread]:
syscall.Syscall6(0x7ffcd4681730, 0x5, 0x134, 0xc00827e700, 0x20, 0xc0003e78e8, 0x0, 0x0, 0x0, 0x0, ...)
	C:/Go/src/runtime/syscall_windows.go:199 +0xed
syscall.WriteConsole(0x134, 0xc00827e700, 0x20, 0xc0003e78e8, 0x0, 0x20, 0x0)
	C:/Go/src/syscall/zsyscall_windows.go:1297 +0xb6
internal/poll.(*FD).writeConsole(0xc000082500, 0xc0001048a0, 0x20, 0x20, 0x4e39f2, 0xc00008c030, 0x1d)
	C:/Go/src/internal/poll/fd_windows.go:735 +0x36b
internal/poll.(*FD).Write(0xc000082500, 0xc0001048a0, 0x20, 0x20, 0x0, 0x0, 0x0)
	C:/Go/src/internal/poll/fd_windows.go:676 +0x19c
os.(*File).write(...)
	C:/Go/src/os/file_windows.go:224
os.(*File).Write(0xc000080010, 0xc0001048a0, 0x20, 0x20, 0xaf4c60, 0x0, 0x0)
	C:/Go/src/os/file.go:145 +0x77
log.(*Logger).Output(0xc00008c000, 0x2, 0xc01c2fb750, 0xc, 0x0, 0x0)
	C:/Go/src/log/log.go:172 +0x205
log.Println(0xc0003e7fc0, 0x1, 0x1)
	C:/Go/src/log/log.go:308 +0x73
main.main.func1()
	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:13 +0x84
created by main.main
	D:/jusanban/doc/50-編碼實現/GO/src/pprofDemo/demo.go:11 +0x40

goroutine 66 [runnable]:
internal/poll.runtime_pollWait(0x1460dd8, 0x72, 0x869ee0)
	C:/Go/src/runtime/netpoll.go:182 +0x5d
internal/poll.(*pollDesc).wait(0xc000100748, 0x72, 0xab8400, 0x0, 0x0)
	C:/Go/src/internal/poll/fd_poll_runtime.go:87 +0xa2
internal/poll.(*ioSrv).ExecIO(0xaf2b90, 0xc000100598, 0x8070b8, 0x40c043, 0xc000038680, 0x40)
	C:/Go/src/internal/poll/fd_windows.go:228 +0x124
internal/poll.(*FD).Read(0xc000100580, 0xc00bbc0000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	C:/Go/src/internal/poll/fd_windows.go:502 +0x26b
net.(*netFD).Read(0xc000100580, 0xc00bbc0000, 0x1000, 0x1000, 0xc000038680, 0xc00b163938, 0x6931f8)
	C:/Go/src/net/fd_windows.go:152 +0x56
net.(*conn).Read(0xc000006020, 0xc00bbc0000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	C:/Go/src/net/net.go:177 +0x70
net/http.(*connReader).Read(0xc00006d200, 0xc00bbc0000, 0x1000, 0x1000, 0x30000, 0x5, 0x30000)
	C:/Go/src/net/http/server.go:787 +0x10e
bufio.(*Reader).fill(0xc0000d0120)
	C:/Go/src/bufio/bufio.go:100 +0x116
bufio.(*Reader).ReadSlice(0xc0000d0120, 0xa, 0x1cb888, 0xc00b163b00, 0x40c043, 0xc0000dc300, 0x100)
	C:/Go/src/bufio/bufio.go:356 +0x44
bufio.(*Reader).ReadLine(0xc0000d0120, 0xc00b163b08, 0xc000008e00, 0x1c06b0, 0x0, 0x40c8ff, 0x30)
	C:/Go/src/bufio/bufio.go:385 +0x3b
net/textproto.(*Reader).readLineSlice(0xc00006d230, 0xc0000dc300, 0xc000100580, 0x0, 0x0, 0x42f1b8)
	C:/Go/src/net/textproto/reader.go:55 +0x76
net/textproto.(*Reader).ReadLine(...)
	C:/Go/src/net/textproto/reader.go:36
net/http.readRequest(0xc0000d0120, 0x0, 0xc0000dc300, 0x0, 0x0)
	C:/Go/src/net/http/request.go:968 +0x94
net/http.(*conn).readRequest(0xc000054280, 0x86fa20, 0xc000038640, 0x0, 0x0, 0x0)
	C:/Go/src/net/http/server.go:967 +0x16a
net/http.(*conn).serve(0xc000054280, 0x86fa20, 0xc000038640)
	C:/Go/src/net/http/server.go:1819 +0x6af
created by net/http.(*Server).Serve
	C:/Go/src/net/http/server.go:2884 +0x2fb

goroutine 41 [runnable]:
net/http.(*connReader).backgroundRead(0xc0000e8990)
	C:/Go/src/net/http/server.go:676
created by net/http.(*connReader).startBackgroundRead
	C:/Go/src/net/http/server.go:673 +0xd1

4. 通過交互式終端分析

4.1 時長爲60s的CPU佔用分析

程序運行情況下,命令行輸入:

go tool pprof http://localhost:6060/debug/pprof/profile?seconds=60

結果輸出:

PS D:\jusanban\doc\50-編碼實現\GO\src\pprofDemo> go tool pprof http://localhost:6060/debug/pprof/profile?seconds=60
Fetching profile over HTTP from http://localhost:6060/debug/pprof/profile?seconds=60
Saved profile in C:\Users\dd\pprof\pprof.samples.cpu.016.pb.gz
Type: cpu
Time: Aug 10, 2019 at 8:07pm (CST)
Duration: 1mins, Total samples = 1.01mins (100.51%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof)

執行該命令後,需等待 60 秒(可調整 seconds 的值),pprof 會進行 CPU Profiling。結束後將默認進入 pprof 的交互式命令模式,可以對分析的結果進行查看或導出。具體可執行 pprof help 查看命令說明。

4.1.1 top

top查看前10行數的CPU佔用情況:

(pprof) top
Showing nodes accounting for 56.49s, 93.48% of 60.43s total
Dropped 125 nodes (cum <= 0.30s)
Showing top 10 nodes out of 25
      flat  flat%   sum%        cum   cum%
    53.72s 88.90% 88.90%     54.03s 89.41%  runtime.cgocall
     0.50s  0.83% 89.72%     56.20s 93.00%  internal/poll.(*FD).writeConsole
     0.45s  0.74% 90.47%      0.86s  1.42%  runtime.mallocgc
     0.36s   0.6% 91.06%      0.36s   0.6%  runtime.memmove
     0.36s   0.6% 91.66%      0.36s   0.6%  unicode/utf8.DecodeRune
     0.27s  0.45% 92.11%      0.54s  0.89%  unicode/utf16.Encode
     0.25s  0.41% 92.52%      0.31s  0.51%  runtime.deferreturn
     0.24s   0.4% 92.92%      0.44s  0.73%  runtime.scanobject
     0.18s   0.3% 93.22%     54.74s 90.58%  syscall.WriteConsole
     0.16s  0.26% 93.48%     57.88s 95.78%  log.(*Logger).Output

【說明】

  • flat:採樣時,該函數正在運行的次數*採樣頻率(10ms),即得到估算的函數運行”採樣時間”。這裏不包括函數等待子函數返回;
  • flat%:同上的 CPU 運行耗時總比例;
  • sum%:給定函數累積使用 CPU 總比例,如第二行 sum% = 89.72% = 88.90% + 0.83%
  • cum:當前函數加上它之上的調用運行總耗時,包括函數等待子函數返回。因此 flat <= cum;
  • cum%:同上的 CPU 運行耗時總比例
  • 最後一列爲函數名稱;
4.1.2 tree

樹形結構查看goroutine情況。

(pprof) tree
Showing nodes accounting for 57.12s, 94.52% of 60.43s total
Dropped 125 nodes (cum <= 0.30s)
----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context
----------------------------------------------------------+-------------
                                            54.03s   100% |   syscall.Syscall6
    53.72s 88.90% 88.90%     54.03s 89.41%                | runtime.cgocall
----------------------------------------------------------+-------------
                                            56.20s   100% |   internal/poll.(*FD).Write
     0.50s  0.83% 89.72%     56.20s 93.00%                | internal/poll.(*FD).writeConsole
                                            54.74s 97.40% |   syscall.WriteConsole
                                             0.54s  0.96% |   unicode/utf16.Encode
                                             0.36s  0.64% |   unicode/utf8.DecodeRune
----------------------------------------------------------+-------------
                                             0.37s 43.02% |   runtime.slicebytetostring
                                             0.31s 36.05% |   runtime.convTstring
                                             0.15s 17.44% |   unicode/utf16.Encode
     0.45s  0.74% 90.47%      0.86s  1.42%                | runtime.mallocgc
----------------------------------------------------------+-------------
                                             0.16s 44.44% |   pprofDemo/data.Add
                                             0.09s 25.00% |   log.(*Logger).formatHeader
                                             0.07s 19.44% |   fmt.Sprintln
     0.36s   0.6% 91.06%      0.36s   0.6%                | runtime.memmove
----------------------------------------------------------+-------------
                                             0.36s   100% |   internal/poll.(*FD).writeConsole
     0.36s   0.6% 91.66%      0.36s   0.6%                | unicode/utf8.DecodeRune
----------------------------------------------------------+-------------
                                             0.54s   100% |   internal/poll.(*FD).writeConsole
     0.27s  0.45% 92.11%      0.54s  0.89%                | unicode/utf16.Encode
                                             0.15s 27.78% |   runtime.mallocgc
----------------------------------------------------------+-------------
                                             0.21s 67.74% |   syscall.Syscall6
                                             0.08s 25.81% |   internal/poll.(*FD).Write
     0.25s  0.41% 92.52%      0.31s  0.51%                | runtime.deferreturn
----------------------------------------------------------+-------------
                                             0.44s   100% |   runtime.gcDrain
     0.24s   0.4% 92.92%      0.44s  0.73%                | runtime.scanobject
----------------------------------------------------------+-------------
                                            54.74s   100% |   internal/poll.(*FD).writeConsole
     0.18s   0.3% 93.22%     54.74s 90.58%                | syscall.WriteConsole
                                            54.49s 99.54% |   syscall.Syscall6
----------------------------------------------------------+-------------
                                            57.88s   100% |   log.Println
     0.16s  0.26% 93.48%     57.88s 95.78%                | log.(*Logger).Output
                                            56.80s 98.13% |   os.(*File).Write
                                             0.56s  0.97% |   log.(*Logger).formatHeader
----------------------------------------------------------+-------------
                                             0.56s   100% |   log.(*Logger).Output
     0.13s  0.22% 93.70%      0.56s  0.93%                | log.(*Logger).formatHeader
                                             0.09s 16.07% |   runtime.memmove
----------------------------------------------------------+-------------
                                            54.49s   100% |   syscall.WriteConsole
     0.11s  0.18% 93.88%     54.49s 90.17%                | syscall.Syscall6
                                            54.03s 99.16% |   runtime.cgocall
                                             0.21s  0.39% |   runtime.deferreturn
----------------------------------------------------------+-------------
                                            56.70s   100% |   os.(*File).write
     0.09s  0.15% 94.03%     56.70s 93.83%                | internal/poll.(*FD).Write
                                            56.20s 99.12% |   internal/poll.(*FD).writeConsole
                                             0.08s  0.14% |   runtime.deferreturn
----------------------------------------------------------+-------------
                                             0.79s   100% |   main.main.func1
     0.07s  0.12% 94.14%      0.79s  1.31%                | pprofDemo/data.Add
                                             0.32s 40.51% |   runtime.slicebytetostring
                                             0.16s 20.25% |   runtime.memmove
                                             0.14s 17.72% |   runtime.systemstack
----------------------------------------------------------+-------------
                                            56.76s   100% |   os.(*File).Write
     0.06s 0.099% 94.24%     56.76s 93.93%                | os.(*File).write
                                            56.70s 99.89% |   internal/poll.(*FD).Write
----------------------------------------------------------+-------------
                                             0.64s   100% |   log.Println
     0.05s 0.083% 94.32%      0.64s  1.06%                | fmt.Sprintln
                                             0.08s 12.50% |   runtime.slicebytetostring
                                             0.07s 10.94% |   runtime.memmove
----------------------------------------------------------+-------------
                                            56.80s   100% |   log.(*Logger).Output
     0.04s 0.066% 94.39%     56.80s 93.99%                | os.(*File).Write
                                            56.76s 99.93% |   os.(*File).write
----------------------------------------------------------+-------------
                                             0.34s   100% |   main.main.func1
     0.03s  0.05% 94.44%      0.34s  0.56%                | runtime.convTstring
                                             0.31s 91.18% |   runtime.mallocgc
----------------------------------------------------------+-------------
                                            58.54s   100% |   main.main.func1
     0.02s 0.033% 94.47%     58.54s 96.87%                | log.Println
                                            57.88s 98.87% |   log.(*Logger).Output
                                             0.64s  1.09% |   fmt.Sprintln
----------------------------------------------------------+-------------
                                             0.32s 80.00% |   pprofDemo/data.Add
                                             0.08s 20.00% |   fmt.Sprintln
     0.02s 0.033% 94.51%      0.40s  0.66%                | runtime.slicebytetostring
                                             0.37s 92.50% |   runtime.mallocgc
----------------------------------------------------------+-------------
     0.01s 0.017% 94.52%     59.68s 98.76%                | main.main.func1
                                            58.54s 98.09% |   log.Println
                                             0.79s  1.32% |   pprofDemo/data.Add
                                             0.34s  0.57% |   runtime.convTstring
----------------------------------------------------------+-------------
         0     0% 94.52%      0.55s  0.91%                | runtime.gcBgMarkWorker
                                             0.55s   100% |   runtime.systemstack
----------------------------------------------------------+-------------
                                             0.63s   100% |   runtime.systemstack
         0     0% 94.52%      0.63s  1.04%                | runtime.gcBgMarkWorker.func2
                                             0.63s   100% |   runtime.gcDrain
----------------------------------------------------------+-------------
                                             0.63s   100% |   runtime.gcBgMarkWorker.func2
         0     0% 94.52%      0.63s  1.04%                | runtime.gcDrain
                                             0.44s 69.84% |   runtime.scanobject
----------------------------------------------------------+-------------
                                             0.55s 63.95% |   runtime.gcBgMarkWorker
                                             0.14s 16.28% |   pprofDemo/data.Add
         0     0% 94.52%      0.86s  1.42%                | runtime.systemstack
                                             0.63s 73.26% |   runtime.gcBgMarkWorker.func2
----------------------------------------------------------+-------------
(pprof)
4.1.3 exit

退出分析,輸入exit命令。

(pprof) exit
PS D:\jusanban\doc\50-編碼實現\GO\src\pprofDemo>

4.2 heap堆分析

go tool pprof http://localhost:6060/debug/pprof/heap

輸出結果:

PS D:\jusanban\doc\50-編碼實現\GO\src\pprofDemo> go tool pprof http://localhost:6060/debug/pprof/heap
Fetching profile over HTTP from http://localhost:6060/debug/pprof/heap
Saved profile in C:\Users\dd\pprof\pprof.alloc_objects.alloc_space.inuse_objects.inuse_space.002.pb.gz
Type: inuse_space
Time: Aug 10, 2019 at 8:20pm (CST)
Entering interactive mode (type "help" for commands, "o" for options)

輸入top,可以得知所有棧內存被.Add函數佔有,合計410M。

(pprof) top
Showing nodes accounting for 410.42MB, 100% of 410.42MB total
      flat  flat%   sum%        cum   cum%
  410.42MB   100%   100%   410.42MB   100%  pprofDemo/data.Add
         0     0%   100%   410.42MB   100%  main.main.func1
(pprof)

4.3 stack棧分析

go tool pprof http://localhost:6060/debug/pprof/allocs

輸出結果:

PS D:\jusanban\doc\50-編碼實現\GO\src\pprofDemo> go tool pprof http://localhost:6060/debug/pprof/allocs
Fetching profile over HTTP from http://localhost:6060/debug/pprof/allocs
Saved profile in C:\Users\dd\pprof\pprof.alloc_objects.alloc_space.inuse_objects.inuse_space.006.pb.gz
Type: alloc_space
Time: Aug 10, 2019 at 8:33pm (CST)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 5127.36MB, 99.83% of 5135.88MB total
Dropped 22 nodes (cum <= 25.68MB)
      flat  flat%   sum%        cum   cum%
 2811.26MB 54.74% 54.74%  2811.26MB 54.74%  pprofDemo/data.Add
 1527.09MB 29.73% 84.47%  1527.09MB 29.73%  unicode/utf16.Encode
  395.51MB  7.70% 92.17%  5127.36MB 99.83%  main.main.func1
  393.51MB  7.66% 99.83%   393.51MB  7.66%  fmt.Sprintln
         0     0% 99.83%  1527.09MB 29.73%  internal/poll.(*FD).Write
         0     0% 99.83%  1527.09MB 29.73%  internal/poll.(*FD).writeConsole
         0     0% 99.83%  1527.09MB 29.73%  log.(*Logger).Output
         0     0% 99.83%  1920.60MB 37.40%  log.Println
         0     0% 99.83%  1527.09MB 29.73%  os.(*File).Write
         0     0% 99.83%  1527.09MB 29.73%  os.(*File).write
(pprof)

該命令等同於go tool pprof -alloc_objects http://localhost:6060/debug/pprof/heap的結果。

4.4 其他

go tool pprof http://localhost:6060/debug/pprof/block
go tool pprof http://localhost:6060/debug/pprof/goroutine
go tool pprof http://localhost:6060/debug/pprof/threadcreate

5. PProf 可視化界面

go tool pprof http://localhost:6060/debug/pprof/profile?seconds=60
go tool pprof -http=:8080 http://localhost:6060/debug/pprof/profile?seconds=60

【說明】
-http=:8080 表示啓動PProf 可視化界面。默認情況下,會瀏覽器打開輸出圖形界面。

例如:

#####【常見問題1】Could not execute dot; may need to install graphviz.
【原因】說明沒有安裝 graphviz 。請參考2.2完成Graphviz安裝。

【常見問題2】open cpu.prof: The system cannot find the file specified

【場景】運行命令,以便圖形化界面輸出。

go tool pprof -http=:8080 cpu.prof

【原因】輝哥在windows下遇到的問題,丁恆在MAC下並沒有遇到。後來我分析,需要先輸出.prof文件,然後使用圖形化查看即可。
例如以下命令即可呈現CPU佔用的圖形化界面分析。

go tool pprof -http=:8080 C:\Users\dd\pprof\pprof.samples.cpu.005.pb.gz

6. go-torch火焰圖生成工具

go-torch是Uber公司開源的一款針對Golang程序的火焰圖生成工具,能收集 stack traces,並把它們整理成火焰圖,直觀地程序給開發人員。go-torch是基於使用BrendanGregg創建的火焰圖工具生成直觀的圖像,很方便地分析Go的各個方法所佔用的CPU的時間。
go-torch命令的幫助說明如下:

PS D:\jusanban\doc\50-編碼實現\GO\src\pprofDemo> go-torch -h
Usage:
  D:\jusanban\doc\50-編碼實現\GO\bin\go-torch.exe [options] [binary] <profile source>

pprof Options:
  /u, /url:          Base URL of your Go program (default: http://localhost:8080)
      /suffix:       URL path of pprof profile (default: /debug/pprof/profile)
  /b, /binaryinput:  File path of previously saved binary profile. (binary profile is anything
                     accepted by https://golang.org/cmd/pprof)
      /binaryname:   File path of the binary that the binaryinput is for, used for pprof inputs
  /t, /seconds:      Number of seconds to profile for (default: 30)
      /pprofArgs:    Extra arguments for pprof

Output Options:
  /f, /file:         Output file name (must be .svg) (default: torch.svg)
  /p, /print         Print the generated svg to stdout instead of writing to file
  /r, /raw           Print the raw call graph output to stdout instead of creating a flame graph;
                     use with Brendan Gregg's flame graph perl script (see
                     https://github.com/brendangregg/FlameGraph)
      /title:        Graph title to display in the output file (default: Flame Graph)
      /width:        Generated graph width (default: 1200)
      /hash          Colors are keyed by function name hash
      /colors:       set color palette. choices are: hot (default), mem, io, wakeup, chain, java,
                     js, perl, red, green, blue, aqua, yellow, purple, orange
      /cp            Use consistent palette (palette.map)
      /reverse       Generate stack-reversed flame graph
      /inverted      icicle graph

Help Options:
  /?                 Show this help message
  /h, /help          Show this help message

6.1 安裝go-torch

WINDOWS命令行安裝go-torch:

go get github.com/uber/go-torch

然後進入go-torch安裝目錄,安裝FlameGraph。例如:

cd D:\jusanban\doc\50-編碼實現\GO\src\github.com\uber\go-torch
git clone https://github.com/brendangregg/FlameGraph.git

然後將FlameGraph路徑添加到Path環境變量中。

D:\jusanban\doc\50-編碼實現\GO\src\github.com\uber\go-torch\FlameGraph

6.2 下載安裝 Perl ,用於執行 .pl 文件

要執行.pl文件,需要安裝 Perl 語言的運行環境,windows 10 安裝 ActivePerl。
從官網或者百度網盤直接下載源程序按照默認設置完成安裝。
https://pan.baidu.com/s/107UTzX-9_vgFPTW93Ec3AA

檢查是否按照成功

命令行輸入perl -v即可檢查是否已經安裝成功。

perl -v

This is perl 5, version 26, subversion 3 (v5.26.3) built for MSWin32-x64-multi-thread
(with 2 registered patches, see perl -V for more detail)

Copyright 1987-2018, Larry Wall

Binary build 2603 [a95bce075] provided by ActiveState http://www.ActiveState.com
Built Dec 17 2018 09:46:45

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

PS D:\jusanban\doc\50-編碼實現\GO\src\github.com\uber\go-torch>
【常見問題3】0mFailed: could not generate flame graph

【問題現象】

go-torch -u http://localhost:6060 -t 30
?[34mINFO[16:11:20] ?[0mRun pprof command: go tool pprof -raw -seconds 30 http://localhost:6060/debug/pprof/profile
?[31mFATAL[16:11:54] ?[0mFailed: could not generate flame graph: Cannot find flamegraph scripts in the PATH or current directory. You can download the script at https://github.com/brendangregg/FlameGraph. These scripts should be added to your PATH or in the directory where go-torch is executed. Alternatively, you can run go-torch with the --raw flag.

【原因及解決方法】
生不出火焰圖,原因爲flamegraph.pl不是有效的可執行文件。在WINDOWS下,需要安裝perl才能執行這個文件呢。

6.3 生成並分析火焰圖

命令含輸入

go-torch /u http://localhost:6060/debug/pprof/ /f cpu-local.svg

結果:

go-torch /u http://localhost:6060/debug/pprof/ /f cpu-local.svg
?[34mINFO[21:29:54] ?[0mRun pprof command: go tool pprof -raw -seconds 30 http://localhost:6060/debug/pprof/profile
?[34mINFO[21:30:26] ?[0mWriting svg to cpu-local.svg

在瀏覽器下打開生成的cpu-local.svg文件,可以看到火焰圖情況。

【火焰圖分析】

y 軸表示調用棧,每一層都是一個函數。調用棧越深,火焰就越高,頂部就是正在執行的函數,下方都是它的父函數。

x 軸表示抽樣數,如果一個函數在 x 軸佔據的寬度越寬,就表示它被抽到的次數多,即執行的時間長。注意,x 軸不代表時間,而是所有的調用棧合併後,按字母順序排列的。

火焰圖就是看頂層的哪個函數佔據的寬度最大。只要有"平頂"(plateaus),就表示該函數可能存在性能問題。

顏色沒有特殊含義,因爲火焰圖表示的是 CPU 的繁忙程度,所以一般選擇暖色調。

7. 高性能程序建議

以下是一些從其它項目借鑑或者自己總結的實踐經驗,它們只是建議,而不是準則,實際項目中應該以性能分析數據來作爲優化的參考,避免過早優化。

  1. 對頻繁分配的小對象,使用sync.Pool對象池避免分配
  2. 自動化的 DeepCopy 是非常耗時的,其中涉及到反射,內存分配,容器(如 map)擴展等,大概比手動拷貝慢一個數量級
  3. 用 atomic.Load/StoreXXX,atomic.Value, sync.Map 等代替 Mutex。(優先級遞減)
  4. 使用高效的第三方庫,如用fasthttp替代 net/http
  5. 在開發環境加上-race編譯選項進行競態檢查
  6. 在開發環境開啓 net/http/pprof,方便實時 pprof
  7. 將所有外部IO(網絡IO,磁盤IO)做成異步

8.參考

(1)Go學習之路-代碼性能監控pprof
https://www.jianshu.com/p/60c0c178212a
【點評】丁恆輸出,有實踐內容。

(2)gprof使用介紹
https://blog.csdn.net/linquidx/article/details/5916701

(3)go pprof 性能分析
https://juejin.im/entry/5ac9cf3a518825556534c76e

(4)Golang 大殺器之性能剖析 PProf
https://segmentfault.com/a/1190000016412013

(5)golang pprof 實戰
https://blog.wolfogre.com/posts/go-ppof-practice/
【點評】整理得不錯。

(6)使用pprof分析cpu佔用過高問題
https://studygolang.com/articles/21841
【點評】CPU佔用過高樣例分析

(7)Golang性能測試工具PProf應用詳解
https://studygolang.com/articles/19024?fr=sidebar

(8)windows下Graphviz安裝及入門教程
https://blog.csdn.net/lanchunhui/article/details/49472949

(9)golang學習筆記-pprof性能分析1
https://blog.csdn.net/qq_30549833/article/details/89378933

(10)golang學習筆記-pprof性能分析2
https://blog.csdn.net/qq_30549833/article/details/89381790

(11)golang 使用pprof和go-torch做性能分析 – Windows
https://www.jianshu.com/p/a22174de24c7

(12)windows 10 下載安裝 Perl ,用於執行 .pl 文件。
https://www.jianshu.com/p/e0d593217756

(13)如何讀懂火焰圖?
http://www.ruanyifeng.com/blog/2017/09/flame-graph.html

(14)pprof & 火焰圖go-torch
https://blog.csdn.net/u014229215/article/details/88837767

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章