1 回答

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 行分配的字節數相等。
- 1 回答
- 0 關注
- 82 瀏覽
添加回答
舉報