multiprocessing.manager管理的对象需要加锁吗_Go: 内存管理和分配
本文基于Go1.13
當(dāng)不再使用內(nèi)存時(shí),標(biāo)準(zhǔn)庫(kù)會(huì)自動(dòng)執(zhí)行Go的內(nèi)存管理即從分配到回收。盡管開發(fā)者不需要處理它,但是Go的底層管理進(jìn)行了很好的優(yōu)化并且充滿了有趣的概念。
堆上的分配
內(nèi)存管理被設(shè)計(jì)可以在并發(fā)環(huán)境快速執(zhí)行并且集成了gc。讓我們從一個(gè)例子開始:
package maintype smallStruct struct {a, b int64c, d float64 }func main() {smallAllocation() }//go:noinline func smallAllocation() *smallStruct {return &smallStruct{} }注釋//go:noinline 將會(huì)阻止內(nèi)聯(lián)優(yōu)化,以避免內(nèi)聯(lián)通過(guò)移除函數(shù)的方式優(yōu)化這段代碼,從而造成最終沒(méi)有分配內(nèi)存的情況。
運(yùn)行逃逸分析命令go tool compile "-m" main.go可以確認(rèn)Go執(zhí)行了分配:
main.go:14:9: &smallStruct literal escapes to heap借助go tool compile -S main.go 輸出的程序匯編代碼,同樣可以明確的展示了分配:
0x001d 00029 (main.go:14) LEAQ type."".smallStruct(SB), AX 0x0024 00036 (main.go:14) PCDATA $0, $0 0x0024 00036 (main.go:14) MOVQ AX, (SP) 0x0028 00040 (main.go:14) CALL runtime.newobject(SB)函數(shù)newobject是新分配對(duì)象和代理mallocgc的內(nèi)置函數(shù),該函數(shù)在堆上管理它們。Go中有兩種策略,一種用于較小的分配,一種用于較大的分配。
小分配
對(duì)于低于32kb的小分配,Go將會(huì)嘗試從本地mcache 緩存中獲取內(nèi)存。此緩存包含一組mspan
每個(gè)M 被分配給一個(gè)處理器P并且一次只能處理一個(gè)goroutine。當(dāng)需要分配內(nèi)存時(shí),當(dāng)前goroutine會(huì)使用它當(dāng)前P的本地緩存來(lái)從中尋找第一個(gè)可用空閑對(duì)象。使用本地緩存不需要加鎖會(huì)使得分配更加高效。
mspan被分為約70個(gè)尺寸類型,從8字節(jié)到32k字節(jié)。
每個(gè)mspan會(huì)存在2次:一個(gè)不包含指針,一個(gè)包含指針。這種區(qū)別會(huì)使得gc更加容易因?yàn)樗恍枰獟呙枘切┎话羔樀膍span。
在我們之前的例子里,結(jié)構(gòu)體是32字節(jié)所以它適合于32 字節(jié)的mspan。
現(xiàn)在會(huì)疑惑如果mspan在內(nèi)存分配時(shí)候沒(méi)有空閑插槽會(huì)發(fā)生什么。Go維護(hù)了包含全尺寸類型的中央鏈表mcentral,其中包含空閑和非空閑對(duì)象的mspan:
mcentral 維護(hù)著mspan的雙向鏈表; 在非空鏈表(non-empty list:尚有空閑object的mspan鏈表) — 非空(“non-empty” )代表鏈表中至少有一個(gè)插槽是空閑可供分配 — 可能包含一些正在使用的內(nèi)存。當(dāng)gc 清理內(nèi)存時(shí),他會(huì)清理一部分mspan標(biāo)記不再使用,并放回非空鏈表(non-empty list)
我們程序可以在插槽耗盡后向中央鏈表申請(qǐng)mspan:
如果空鏈表中沒(méi)有可用的mspan,Go需要為中央鏈表獲取新的mspan。新的mspan會(huì)從堆上分配并鏈接到中央鏈表上:
堆在需要時(shí)從OS中提取內(nèi)存。如果需要更多內(nèi)存,堆會(huì)分配一個(gè)叫做 arena 的大塊內(nèi)存, 在 64 位架構(gòu)下為 64Mb,在其他架構(gòu)下大多為 4Mb。arena 同樣使用mspan來(lái)映射內(nèi)存:
大分配
Go并不適用本地緩存來(lái)管理較大的內(nèi)存空間分配。對(duì)于超過(guò) 32kb 的分配,會(huì)向上取整到頁(yè)的大小,并直接從堆上分配。
全景圖
現(xiàn)在我們對(duì)內(nèi)存分配的時(shí)候發(fā)生了什么有了更好的認(rèn)識(shí)。現(xiàn)在將所有的組成部分放在一起來(lái)得到全景圖:
編譯整理自 Go: Memory Management and Allocationhttps://medium.com/a-journey-with-go/go-memory-management-and-allocation-a7396d430f44總結(jié)
以上是生活随笔為你收集整理的multiprocessing.manager管理的对象需要加锁吗_Go: 内存管理和分配的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 美白牙齿要多少钱啊?
- 下一篇: 3d中了多少钱啊?