亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Go 如何以及何時為有界隊列通道分配內存?

Go 如何以及何時為有界隊列通道分配內存?

Go
偶然的你 2022-07-25 10:33:08
我正在使用 Go 的 pprof 工具來調查我的服務的內存使用情況。幾乎所有的內存使用都來自一個設置多個有界隊列通道的函數。我對 pprof 在這里告訴我的內容有些困惑:$ go tool pprof ~/pprof/pprof.server.alloc_objects.alloc_space.inuse_objects.inuse_space.007.pb.gzFile: serverType: inuse_spaceTime: Dec 21, 2020 at 10:46am (PST)Entering interactive mode (type "help" for commands, "o" for options)(pprof) list fooTotal: 102.73MBROUTINE ======================== github.com/******/foo in ***.go   79.10MB    79.10MB (flat, cum) 77.00% of Total         .          .    135:         .          .    136:func foo() {         .          .    137:       14.04MB    14.04MB    138:    chanA := make(chan chanAEntry, bufferSize)         .          .    139:    defer close(chanA)         .          .    140:         .          .    141:       19.50MB    19.50MB    142:    chanB := make(chan chanBCEntry, bufferSize)         .          .    143:    defer close(chanB)         .          .    144:         .          .    145:       27.53MB    27.53MB    146:    chanC := make(chan chanBCEntry, bufferSize)         .          .    147:    defer close(chanC)         .          .    148:         .          .    149:        7.92MB     7.92MB    150:    chanD := make(chan chanDEntry, bufferSize)         .          .    151:    defer close(chanD)         .          .    152:看起來第 142 行負責 19.50MB 的分配,第 146 行負責 27.53MB,但這些行做的是同樣的事情——它們創建具有相同輸入類型和相同容量的緩沖通道。這是 pprof 進行隨機抽樣這一事實的產物嗎?Go 是否會延遲分配通道(fwiw,在讓服務運行幾天后,這些值最終會均衡)?pprof 是否報告了沿通道發送的對象所需的內存以及通道本身所需的內存?
查看完整描述

1 回答

?
ITMISS

TA貢獻1871條經驗 獲得超8個贊

好的,我相信我已經想通了??雌饋?Go 急切地分配并且差異只是由于 Go 內存分析器采樣的方式。

Go 急切地分配通道內存

承諾的文檔_make

通道的緩沖區使用指定的緩沖區容量進行初始化。

我查看了makechan的代碼,它在make(chan chantype, size). 它總是直接調用mallocgc- 沒有懶惰。

查看mallocgc的代碼,我們可以確認其中沒有惰性mallocgc(除了文檔注釋沒有提到惰性,直接mallocgc調用c.alloc)。

pprof 在堆分配級別采樣,而不是在調用函數級別

在環顧四周mallocgc時,我發現了分析代碼。在每次mallocgc調用中,Go 都會檢查是否滿足其采樣條件。如果是這樣,它會調用mProf_Malloc將記錄添加到堆配置文件中。我無法確認這是 使用的配置文件pprof,但該文件中的注釋表明它是。

采樣條件基于自上次采樣以來分配的字節數(它從指數分布中抽取樣本,平均而言,在每個runtime.MemProfileRate字節分配后)。

這里的重要部分是每次調用mallocgc都有一定的抽樣概率,而不是每次調用foo. 這意味著如果對 的調用對foo進行多次調用mallocgc,我們預計只會對部分mallocgc調用進行采樣。

把它們放在一起

每次我的函數foo運行時,它都會急切地為 4 個通道分配內存。在每次內存分配調用中,Go 都有機會記錄堆配置文件。平均而言,Go 將每 512kB 記錄一次堆配置文件(runtime.MemProfileRate 的默認值)。由于這些通道的總大小為 488kB,平均而言,我們預計每次foo調用只記錄一個分配。我上面分享的配置文件是在服務重啟后相對較快的,所以分配字節數的差異是純統計差異的結果。讓服務運行一天后,配置文件穩定下來,顯示第 142 行和第 146 行分配的字節數相等。


查看完整回答
反對 回復 2022-07-25
  • 1 回答
  • 0 關注
  • 82 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號