我有一個(gè) Go 程序可以計(jì)算內(nèi)存中的大型相關(guān)矩陣。為此,我設(shè)置了一個(gè)包含 3 個(gè) goroutine 的管道,第一個(gè)讀取文件,第二個(gè)計(jì)算相關(guān)矩陣,最后一個(gè)將結(jié)果存儲到磁盤。問題是,當(dāng)我運(yùn)行程序時(shí),Go 運(yùn)行時(shí)分配了大約 17GB 的內(nèi)存,而矩陣只占用大約 2-3GB。使用runtime.ReadMemStats顯示該程序正在使用 ~17GB(并使用 htop 驗(yàn)證),但pprof僅報(bào)告約 ~2.3GB。如果我在通過管道運(yùn)行一個(gè)文件后查看內(nèi)存統(tǒng)計(jì)信息:var mem runtime.MemStatsruntime.ReadMemStats(&mem)fmt.Printf("Total alloc: %d GB\n", mem.Alloc/1000/1000/1000)這顯示了程序的總分配:Total alloc: 17 GB但是,如果我運(yùn)行,go tool pprof mem.prof我會得到以下結(jié)果:(pprof) top5Showing nodes accounting for 2.21GB, 100% of 2.21GB totalShowing top 5 nodes out of 9 flat flat% sum% cum cum% 1.20GB 54.07% 54.07% 1.20GB 54.07% dataset.(*Dataset).CalcCorrelationMatrix 1.02GB 45.93% 100% 1.02GB 45.93% bytes.makeSlice 0 0% 100% 1.02GB 45.93% bytes.(*Buffer).WriteByte 0 0% 100% 1.02GB 45.93% bytes.(*Buffer).grow 0 0% 100% 1.02GB 45.93% encoding/json.Indent所以我想知道我如何才能找出程序分配 17 GB 的原因,而峰值內(nèi)存使用量似乎只有 ~2.5GB?有沒有辦法使用 pprof 跟蹤整個(gè)程序的內(nèi)存使用情況?編輯我再次使用 GODEBUG=gctrace=1 運(yùn)行程序并得到以下跟蹤:gc 1 @0.017s 0%: 0.005+0.55+0.003 ms clock, 0.022+0/0.47/0.11+0.012 ms cpu, 1227->1227->1226 MB, 1228 MB goal, 4 Pgc 2 @14.849s 0%: 0.003+1.7+0.004 ms clock, 0.015+0/1.6/0.11+0.018 ms cpu, 1227->1227->1227 MB, 2452 MB goal, 4 Pgc 3 @16.850s 0%: 0.006+60+0.003 ms clock, 0.027+0/0.46/59+0.015 ms cpu, 1876->1876->1712 MB, 2455 MB goal, 4 Pgc 4 @22.861s 0%: 0.005+238+0.003 ms clock, 0.021+0/0.46/237+0.015 ms cpu, 3657->3657->3171 MB, 3658 MB goal, 4 Pgc 5 @30.716s 0%: 0.005+476+0.004 ms clock, 0.022+0/0.44/476+0.017 ms cpu, 5764->5764->5116 MB, 6342 MB goal, 4 Pgc 6 @46.023s 0%: 0.005+949+0.004 ms clock, 0.020+0/0.47/949+0.017 ms cpu, 10302->10302->9005 MB, 10303 MB goal, 4 Pgc 7 @64.878s 0%: 0.006+382+0.004 ms clock, 0.024+0/0.46/382+0.019 ms cpu, 16548->16548->7728 MB, 18011 MB goal, 4 Pgc 8 @89.774s 0%: 0.86+2805+0.006 ms clock, 3.4+0/24/2784+0.025 ms cpu, 20208->20208->17088 MB, 20209 MB goal, 4 P所以很明顯堆在整個(gè)程序中穩(wěn)步增長,但我無法確定在哪里。pprof.WriteHeapProfile我在調(diào)用內(nèi)存密集型函數(shù)后分析了內(nèi)存使用情況:
2 回答

繁星淼淼
TA貢獻(xiàn)1775條經(jīng)驗(yàn) 獲得超11個(gè)贊
go profile 是一個(gè)采樣分析器,并以特定的時(shí)間間隔對內(nèi)存使用情況進(jìn)行采樣。在我的例子中,采樣不夠頻繁,無法捕獲使用大量內(nèi)存的函數(shù)(JSON 編組)。
通過設(shè)置環(huán)境變量增加探查器的采樣率
$ export GODEBUG=memprofilerate=1
將更新runtime.MemProfileRate
并且配置文件現(xiàn)在包括每個(gè)分配的塊。

侃侃爾雅
TA貢獻(xiàn)1801條經(jīng)驗(yàn) 獲得超16個(gè)贊
一個(gè)可能的解決方案(就像我的情況一樣)是二進(jìn)制文件是用 編譯的-race
,這樣可以檢查競爭條件。
這樣做的開銷是巨大的,如果用 或類似的東西檢查的話,看起來像是一個(gè)巨大的內(nèi)存泄漏htop
,但不會顯示在任何 pprof 輸出中
- 2 回答
- 0 關(guān)注
- 188 瀏覽
添加回答
舉報(bào)
0/150
提交
取消