go中的物理內(nèi)存釋放

madvice是go1.16版本引入的系統(tǒng)調(diào)用參數(shù)配置,本文解釋了它的原理和作用。
go 使用 madvise 系統(tǒng)調(diào)用來釋放物理內(nèi)存給操作系統(tǒng),該方法主要有兩種歸還類型可選:
MADV_DONTNEED:立即歸還物理內(nèi)存給操作系統(tǒng),如果下次訪問到該范圍的內(nèi)存,則會觸發(fā) page fault 異常,需要重新分配物理頁,使用該類型可以減少程序的RSS占用MADV_FREE:告訴操作系統(tǒng)這塊內(nèi)存已經(jīng)不需要使用了,可以回收了,如果內(nèi)存緊張,操作系統(tǒng)就會將其回收。這實際是一個lazily的釋放過程。如果再次訪問這塊內(nèi)存的時候,操作系統(tǒng)還沒有將其回收,是不會觸發(fā) page fault 的。使用該類型,可能程序的RSS不會減少。
當前實現(xiàn),首先嘗試使用?MADV_FREE,如果失敗了,再嘗試使用?MADV_DONTNEED。MADV_FREE需要linux內(nèi)核4.5及以上:
var?adviseUnused?=?uint32(_MADV_FREE)
func?sysUnused(v?unsafe.Pointer,?n?uintptr)?{
????......
????
????var?advise?uint32
????//?如果設(shè)置了`GODEBUG=madvdontneed=1`,強制使用MADV_DONTNEED
????if?debug.madvdontneed?!=?0?{
????????advise?=?_MADV_DONTNEED
????}?else?{
????????advise?=?atomic.Load(&adviseUnused)
????}
????//?首先嘗試使用`MADV_FREE`
????if?errno?:=?madvise(v,?n,?int32(advise));?advise?==?_MADV_FREE?&&?errno?!=?0?{
????????//?MADV_FREE?was?added?in?Linux?4.5.?Fall?back?to?MADV_DONTNEED?if?it?is
????????//?not?supported.
????????atomic.Store(&adviseUnused,?_MADV_DONTNEED)
????????madvise(v,?n,?_MADV_DONTNEED)
????}
}
MADV_FREE的性能會好一點,但是會讓程序的RSS占用不會減少,可以通過GODEBUG=madvdontneed=1強制使用MADV_DONTNEED。
go中堆內(nèi)存主要使用mmap來申請的。首先,使用mmap來reserve一段內(nèi)存:
func?sysReserve(v?unsafe.Pointer,?n?uintptr)?unsafe.Pointer?{
?p,?err?:=?mmap(v,?n,?_PROT_NONE,?_MAP_ANON|_MAP_PRIVATE,?-1,?0)
?if?err?!=?0?{
??return?nil
?}
?return?p
}
可以看到,使用匿名映射一塊內(nèi)存,并且指定了 PROT_NONE ,即這塊內(nèi)存是不可以被訪問的,因此就不會分配物理內(nèi)存了。當需要真正分配內(nèi)存的時候,在這塊保留的內(nèi)存中分配:
func?sysMap(v?unsafe.Pointer,?n?uintptr,?sysStat?*uint64)?{
?mSysStatInc(sysStat,?n)?//?內(nèi)存統(tǒng)計
?//?修改前面保留的內(nèi)存的指定區(qū)域為可讀寫
?p,?err?:=?mmap(v,?n,?_PROT_READ|_PROT_WRITE,?_MAP_ANON|_MAP_FIXED|_MAP_PRIVATE,?-1,?0)
?if?err?==?_ENOMEM?{
??throw("runtime:?out?of?memory")
?}
?if?p?!=?v?||?err?!=?0?{
??throw("runtime:?cannot?map?pages?in?arena?address?space")
?}
}
當我們查看進程的內(nèi)存占用時,主要關(guān)注的是RSS,而reserve的內(nèi)存是不能被訪問的,不會分配物理內(nèi)存頁,并不會影響RSS的值。
文章轉(zhuǎn)載:Go開發(fā)大全
(版權(quán)歸原作者所有,侵刪)

點擊下方“閱讀原文”查看更多
評論
圖片
表情
