Go 的分配采用了類似 tcmalloc 的結構.特點: 使用一小塊一小塊的連續內存頁, 進行分配某個范圍大小的內存需求. 比如某個連續 8KB 專門用于分配 17-24 字節,以此減少內存碎片. 線程擁有一定的 cache, 可用于無鎖分配.
同時 Go 對于 GC 后回收的內存頁, 并不是馬上歸還給操作系統, 而是會延遲歸還, 用于滿足未來的內存需求.
??
在 1.10 以前 go 的堆地址空間是線性連續擴展的, 比如在 1.10(linux amd64)中, 最大可擴展到 512GB. 因為 go 在 gc 的時候會根據拿到的指針地址來判斷是否位于 go 的 heap 的, 以及找到其對應的 span, 其判斷機制需要 gc heap 是連續的. 但是連續擴展有個問題, cgo 中的代碼(尤其是 32 位系統上)可能會占用未來會用于 go heap 的內存. 這樣在擴展 go heap 時, mmap 出現不連續的地址, 導致運行時 throw.
在 1.11 中, 改用了稀疏索引的方式來管理整體的內存. 可以超過 512G 內存, 也可以允許內存空間擴展時不連續.在全局的 mheap struct 中有個 arenas 二階數組, 在 linux amd64 上,一階只有一個 slot, 二階有 4M 個 slot, 每個 slot 指向一個 heapArena 結構, 每個 heapArena 結構可以管理 64M 內存, 所以在新的版本中, go 可以管理 4M*64M=256TB 內存, 即目前 64 位機器中 48bit 的尋址總線全部 256TB 內存.
??
go 的內存分配類似于 tcmalloc, 采用了 span 機制來減少內存碎片. 每個 span 管理 8KB 整數倍的內存, 用于分配一定范圍的內存需求.
審核編輯 黃宇
-
內存
+關注
關注
8文章
3034瀏覽量
74136 -
Go
+關注
關注
0文章
43瀏覽量
12262
發布評論請先 登錄
相關推薦
評論