GO堆内存分配

  • 参考tcmalloc实现内存分配器,参照预置大小规格把内存分成块,把不同规格的内存块放入到链表中,最小8字节 最大32KB,共67种
  • go将堆地址空间分配成arena,每个arena大小64M,包含8192个page,每个page 8KB,
  • 在划分arena里又划分不同的span,每个span包含一组连续的page,每个page划分成等大的内存块,
  • areana -> mheap -> page -> 内存块
  • 管理内存的数据结构
  • mheap:用于管理整个堆内存
  • heapArena:对应1个arena
  • mspan:对应mspan结构
  • mheap中有一个central结构,数组,136个长度,数据元素是mcentral结构+padding
  • mcentral结构体:
type mcentral struct {
spanclass spanClass //当前的mspan级别
partial [2]spanSet  // list of spans with a free object
full    [2]spanSet // list of spans with no free objects
}

具体字段使用情况

heapArena

type heapArena struct {
_ sys.NotInHeap
spans [pagesPerArena]*mspan
pageInUse [pagesPerArena / 8]uint8
pageMarks [pagesPerArena / 8]uint8
pageSpecials [pagesPerArena / 8]uint8
checkmarks *checkmarksMap
zeroedBase uintptr
}
  • zeroedBase:arena起始地址
  • spans: 每个page对应的mspn
  • pageInUse:span是否被使用
  • pageMarks:哪些span中存在被标记的对象,

内存分配流程

根据内存分配大小是否小于32KB,分为三种情况

微对象分配
type mcache struct {
_ sys.NotInHeap
nextSample uintptr // trigger heap sample after allocating this many bytes
scanAlloc  uintptr // bytes of scannable heap allocated
tiny       uintptr
tinyoffset uintptr
tinyAllocs uintptr
alloc [numSpanClasses]*mspan // spans to allocate from, indexed by spanClass
stackcache [_NumStackOrders]stackfreelist
flushGen atomic.Uint32
}
  • 小于16字节并且noscan类型,使用tiny分配器,mcache结构中,tiny字段指针用于指向16字节大小的内存单元,tinyoffset记录当前指针偏移量,tinyAllocs记录分配次数,
  • tiny分配器能够将小对象进行合并,提高空间利用率,通过tinyoffset加上本次分配的size,没有超过maxTinySize,直接分配。
  • 否则,通过alloc 字段,从mcentral中获取mspan,从mspan中获取内存,如果mspan中也没空间,从mcentral中取一个新的mspan,
大对象分配
  • 根据需要的页面数分配一个新的span
小对象分配
  • 根据所需大小查找对应span等级,更具noscan和span等级查找mcache里对应的span,如果空间允许,则直接分配,怎么判断空间是否能分配呢?
  • mspan结构体中有freeindex参数指向下一个空闲的对象索引,nelems记录span中所有的对象个数,从freeindex向后扫描,发下n对象空闲,则分配。
  • 如何判断当前对象块是否空闲呢?span结构体还有个allocBits参数,判断当前对象块是否空闲。
  • 如果mcache里不足以分配,就从mcentral里取一个新的span。同理了
位图标记

主要是对heaparena的位图进行标记,标记哪些哪些数据需要GC扫描, 通过内存地址查找对应的heaparena,和对应mspan,主要是更新bitmaps字段,bitmaps字段存放着page是否是标量还是指针,以及扫描终止位。

参考文章

参考文章

results matching ""

    No results matching ""