1 回答

TA貢獻(xiàn)1871條經(jīng)驗(yàn) 獲得超8個(gè)贊
好的,我相信我已經(jīng)想通了。看起來(lái) Go 急切地分配并且差異只是由于 Go 內(nèi)存分析器采樣的方式。
Go 急切地分配通道內(nèi)存
承諾的文檔_make
通道的緩沖區(qū)使用指定的緩沖區(qū)容量進(jìn)行初始化。
我查看了makechan的代碼,它在make(chan chantype, size)
. 它總是直接調(diào)用mallocgc
- 沒(méi)有懶惰。
查看mallocgc的代碼,我們可以確認(rèn)其中沒(méi)有惰性mallocgc
(除了文檔注釋沒(méi)有提到惰性,直接mallocgc
調(diào)用c.alloc
)。
pprof 在堆分配級(jí)別采樣,而不是在調(diào)用函數(shù)級(jí)別
在環(huán)顧四周mallocgc
時(shí),我發(fā)現(xiàn)了分析代碼。在每次mallocgc
調(diào)用中,Go 都會(huì)檢查是否滿足其采樣條件。如果是這樣,它會(huì)調(diào)用mProf_Malloc將記錄添加到堆配置文件中。我無(wú)法確認(rèn)這是 使用的配置文件pprof
,但該文件中的注釋表明它是。
采樣條件基于自上次采樣以來(lái)分配的字節(jié)數(shù)(它從指數(shù)分布中抽取樣本,平均而言,在每個(gè)runtime.MemProfileRate字節(jié)分配后)。
這里的重要部分是每次調(diào)用mallocgc
都有一定的抽樣概率,而不是每次調(diào)用foo
. 這意味著如果對(duì) 的調(diào)用對(duì)foo
進(jìn)行多次調(diào)用mallocgc
,我們預(yù)計(jì)只會(huì)對(duì)部分mallocgc
調(diào)用進(jìn)行采樣。
把它們放在一起
每次我的函數(shù)foo
運(yùn)行時(shí),它都會(huì)急切地為 4 個(gè)通道分配內(nèi)存。在每次內(nèi)存分配調(diào)用中,Go 都有機(jī)會(huì)記錄堆配置文件。平均而言,Go 將每 512kB 記錄一次堆配置文件(runtime.MemProfileRate 的默認(rèn)值)。由于這些通道的總大小為 488kB,平均而言,我們預(yù)計(jì)每次foo
調(diào)用只記錄一個(gè)分配。我上面分享的配置文件是在服務(wù)重啟后相對(duì)較快的,所以分配字節(jié)數(shù)的差異是純統(tǒng)計(jì)差異的結(jié)果。讓服務(wù)運(yùn)行一天后,配置文件穩(wěn)定下來(lái),顯示第 142 行和第 146 行分配的字節(jié)數(shù)相等。
- 1 回答
- 0 關(guān)注
- 80 瀏覽
添加回答
舉報(bào)