Golang程序如何查找內(nèi)存泄漏(pprof)
Golang程序查找內(nèi)存泄漏
1. 在main包中
選擇在一個單獨文件中加上pprof包引用并設置條件編譯,這樣不會與develop正式版本代碼產(chǎn)生任何耦合。
// +build debug package main import ( "net/http" _ "net/http/pprof" ) func init() { go http.ListenAndServe(":18080", nil) }
2. 編譯
go build -tags debug .
3. 在目標機中運行剛編譯出來的debug版本程序
本例中ip為隨意編寫的。
4. 執(zhí)行
go tool pprof -inuse_space http://192.168.20.5:18080/debug/pprof/heap進入交互模式:
[user@LAPTOP-LCP testtool]$ go tool pprof -inuse_space http://192.168.20.5:18080/debug/pprof/heap Fetching profile over HTTP from http://192.168.20.5:18080/debug/pprof/heap Saved profile in C:\Users\Noname\pprof\pprof.testtool.alloc_objects.alloc_space.inuse_objects.inuse_space.006.p b.gz File: testtool Type: inuse_space Time: Aug 16, 2022 at 2:24pm (CST) Entering interactive mode (type "help" for commands, "o" for options) (pprof) top 10 Showing nodes accounting for 27831.78kB, 100% of 27831.78kB total Showing top 10 nodes out of 35 flat flat% sum% cum cum% 11787.50kB 42.35% 42.35% 11787.50kB 42.35% runtime.allocm 9382.95kB 33.71% 76.07% 9382.95kB 33.71% io.ReadAll 2561.02kB 9.20% 85.27% 2561.02kB 9.20% runtime.malg 1536.21kB 5.52% 90.79% 1536.21kB 5.52% github.com/aws/aws-sdk-go/aws/endpoints.init 514kB 1.85% 92.63% 514kB 1.85% bufio.NewReaderSize 514kB 1.85% 94.48% 514kB 1.85% bufio.NewWriterSize 512.08kB 1.84% 96.32% 512.08kB 1.84% net/http.newTransferWriter 512.02kB 1.84% 98.16% 512.02kB 1.84% runtime.gcBgMarkWorker 512kB 1.84% 100% 512kB 1.84% runtime.doaddtimer 0 0% 100% 9382.95kB 33.71% io/ioutil.ReadAll (pprof) (pprof)
交互界面使用top命令查看內(nèi)存分配最多的函數(shù)。
如果本機中有源代碼,可以使用list命令查看源代碼中哪一行分配的函數(shù)最多。
(pprof) (pprof) list io.ReadAll Total: 27.18MB ROUTINE ======================== io.ReadAll in C:\Program Files\Go\src\io\io.go 9.16MB 9.16MB (flat, cum) 33.71% of Total . . 626:func ReadAll(r Reader) ([]byte, error) { . . 627: b := make([]byte, 0, 512) . . 628: for { . . 629: if len(b) == cap(b) { . . 630: // Add more capacity (let append pick how much). 9.16MB 9.16MB 631: b = append(b, 0)[:len(b)] . . 632: } . . 633: n, err := r.Read(b[len(b):cap(b)]) . . 634: b = b[:len(b)+n] . . 635: if err != nil { . . 636: if err == EOF { (pprof) (pprof)
5. 也可以使用以下命令直接導出調(diào)用圖
非常直觀(需要安裝Graphviz,詳詢Download | Graphviz)
go tool pprof -inuse_space -png http://192.168.20.5:18080/debug/pprof/heap > heap.png
可以在圖片中直觀地看到,調(diào)用過程中每個函數(shù)的內(nèi)存使用占比。
出現(xiàn)內(nèi)存泄漏時,如果只查看一次很難確定真正出現(xiàn)內(nèi)存泄露的代碼位置,可以在程序運行一段時間后,程序出現(xiàn)內(nèi)存泄露已經(jīng)很明顯后,再次查看內(nèi)存占用分析圖,找到兩張圖中內(nèi)存占用比例相差最大的函數(shù)。
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Golang使用gob實現(xiàn)結構體的序列化過程詳解
Golang struct類型數(shù)據(jù)序列化用于網(wǎng)絡傳輸數(shù)據(jù)或在磁盤上寫入數(shù)據(jù)。在分布式系統(tǒng)中,一端生成數(shù)據(jù)、然后序列化、壓縮和發(fā)送;在另一端,接收數(shù)據(jù)、然后解壓縮、反序列化和處理數(shù)據(jù),整個過程必須快速有效2023-03-03Golang的循環(huán)中break和continue語句的用法講解
這篇文章主要介紹了Golang的循環(huán)中break和continue語句的用法講解,是Go語言入門學習中的基礎知識,需要的朋友可以參考下2015-10-10通過函數(shù)如何將golang?float64?保留2位小數(shù)(方法匯總)
這篇文章主要介紹了通過函數(shù)將golang?float64保留2位小數(shù),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-08-08