一般程序的內存分配,從高位到低位依次為
全局靜態區:用於存儲全局變量、靜態變量等;這部分內存在程序編譯時已經分配好,由操作系統管理,速度快,不易出錯。
棧:函數中的基礎類型的局部變量;由程序進行系統調用向操作系統申請,由操作系統管理,速度快。每個線程有自己的棧區。
堆:使用malloc或new申請的內存;由程序運行過程中動態分配任意大小的內存,由程序管理,使用free或者delete刪除;頻繁的分配和釋放必然導致內存碎片。
常量區:存放常量字符串,程序結束后由系統釋放。
程序代碼區:存放程序的二進制代碼。
Go的內存分配:
Go是內置運行時runtime的語言;像這種內置運行時的語言會拋棄傳統的內存管理方式,改為自己管理;這樣可以完成類似預分配,內存池等操作,以避開系統調用產生的性能問題。Go的內存分配可以分為以下幾點:
1. 每次從操作系統申請一大塊內存,由Go來對這塊內存做分配,減少系統調用。
2. 內存分配算法采用 TCMalloc算法,核心思想是把內存分的非常細,進行分級管理,以降低鎖的粒度。
3. 回收對象內存時,並沒有將其真正釋放掉,而是放回預先分配的大內存中,以便復用。只有內存閑置過多的時候,才會嘗試歸還部分內存給操作系統,降低整體開銷。
Go在程序啟動的時候,會分配一塊連續的內存(虛擬內存),整體如下:
arena就是所謂的堆區,他把內存分割成 8K大小的頁,頁是heap中的最小管理單位,一些頁組合起來形成了mspan。
bitmap區用於保存arena對應地址(指針大小為 8B,bitmap中一個byte大小的內存對應arena區域中的4個指針,因此大小為 512G/(4 * 8B))中是否保存了對象,以及對象是否被gc過,主要用於gc。
spans區域存放了mspan的指針,用於表示arena區的某一頁屬於哪個mspan。大小為 512G / 8KB(頁的大小) * 8B(指針大小)。在創建 mspan的時候,按頁填充對應的spans區域,在回收object時,很容易找到他所屬的mspan。
Go內存管理結構
1. class和mspan
go對象管理粒度分為67種大小,也叫class和塊。一個page根據class大小分為8K/class size。
class相同且地址連續的pages組成一個span。mspan是span的實際結構,mspan之間組成雙向鏈表關聯。
2. mcache
每個工作線程都有各自的mcache,本地緩存可用的mspan資源,這樣各個線程在申請內存的時候無需加鎖,對於小於32KB大小的對象,直接通過mcache分配;對於大於23KB的大對象,則需要在mheap中分配。
每個goroutine對於同一個class都有scan和noscan兩種mspan隊列,其中scan分配給含有指針的對象,noscan分配給不含指針的對象,這樣做是為了便於進行垃圾回收,在進行垃圾回收的時候,對於不包含指針的對象,無需進一步掃描是否引用其他活躍對象。
3. mcenter
mcenter為所有mcache提供切分好的mspan。有多少種mspan類型的mspan就有多少個mcenter,每個mcenter保存一種特定類型的mspan,提供兩個mspan雙端隊列,包括已分配出去的和未分配出去的。
所有線程共享,需要加鎖訪問,但是申請一種 類型的mspan不會影響其他的mcenter.
type mcentral struct {
lock mutex
spanclass spanClass
nonempty mSpanList // list of spans with a free object, ie a nonempty free list
empty mSpanList // list of spans with no free objects (or cached in an mcache)
// nmalloc is the cumulative count of objects allocated from
// this mcentral, assuming all spans in mcaches are
// fully-allocated. Written atomically, read under STW.
nmalloc uint64
}
4. mheap
代表Go程序的堆空間,Go程序使用一個mheap來管理堆空間。
當mcenter中沒有空閑的mspan時,會向mheap申請。而mheap沒有剩余內存時,會向操作系統申請新內存。
另外,對於大於32Kb的大對象,需要在mheap中分配,所有線程共享,需要加鎖。
參考:
https://zhuanlan.zhihu.com/p/59125443
https://www.cnblogs.com/unqiang/p/12052308.html
https://zhuanlan.zhihu.com/p/128462868