原创

Go内存中各个模块的划分和功能

所有内存管理机制都是通过mheap这个结构体管理的,在下图中Heap实际上指的就是mheap结构体对象

我们一定把这张图和下面的代码对着看,一个个变量对照着看才比较好。
整体结构我先用文字简单概括一下,下面也有图:
所有的内存管理都在mheap这个结构体中完成。

mheap(堆结构体)
注意:这里我们先不用理解每个模块是做什么用的,只要知道结构关系就行。、
成员变量1(一级成员):模块名(模块名只是便于理解)【spans】,真实代码变量名:【allspans】 ,真实变量类型【 []*mspan 】
成员变量2(一级成员):模块名:【arena】,真实代码变量名:【arenas】,真实变量类型【[1 << arenaL1Bits]*[1 << arenaL2Bits]*heapArena】
成员变量3(一级成员): 模块名【central】,真实代码变量名【central】,真实变量类型:【[numSpanClasses]struct{...}】


下面是go源码的mheap结构,我已经把不重要的删除掉了,只留下了关键的对应图中结构的部分。
mheap源码数据结构

type mheap struct {
  
   //第一模块:这个对应上图中的spans模块
   allspans []*mspan // all spans out there

   //第二个模块: 
   //64位windows上:一维数组的长度是:1<<6 = 1*2的六次方= 64
   //61位windows上,二维数组的长度是:
   arenas [1 << arenaL1Bits]*[1 << arenaL2Bits]*heapArena

   //第三大模块
   central [numSpanClasses]struct {
      mcentral mcentral
      pad      [cpu.CacheLinePadSize - unsafe.Sizeof(mcentral{})%cpu.CacheLinePadSize]byte
   }
	
   //	 
   spanalloc             fixalloc // allocator for span*
   cachealloc            fixalloc // allocator for mcache*
   
}   

heapArena源码数据结构

type heapArena struct {
   // bitmap stores the pointer/scalar bitmap for the words in
   // this arena. See mbitmap.go for a description. Use the
   // heapBits type to access this.
   bitmap [heapArenaBitmapBytes]byte

   // spans maps from virtual address page ID within this arena to *mspan.
   // For allocated spans, their pages map to the span itself.
   // For free spans, only the lowest and highest pages map to the span itself.
   // Internal pages map to an arbitrary span.
   // For pages that have never been allocated, spans entries are nil.
   //
   // Modifications are protected by mheap.lock. Reads can be
   // performed without locking, but ONLY from indexes that are
   // known to contain in-use or stack spans. This means there
   // must not be a safe-point between establishing that an
   // address is live and looking it up in the spans array.
   spans [pagesPerArena]*mspan

   // pageInUse is a bitmap that indicates which spans are in
   // state mSpanInUse. This bitmap is indexed by page number,
   // but only the bit corresponding to the first page in each
   // span is used.
   //
   // Reads and writes are atomic.
   pageInUse [pagesPerArena / 8]uint8

   // pageMarks is a bitmap that indicates which spans have any
   // marked objects on them. Like pageInUse, only the bit
   // corresponding to the first page in each span is used.
   //
   // Writes are done atomically during marking. Reads are
   // non-atomic and lock-free since they only occur during
   // sweeping (and hence never race with writes).
   //
   // This is used to quickly find whole spans that can be freed.
   //
   // TODO(austin): It would be nice if this was uint64 for
   // faster scanning, but we don't have 64-bit atomic bit
   // operations.
   pageMarks [pagesPerArena / 8]uint8

   // zeroedBase marks the first byte of the first page in this
   // arena which hasn't been used yet and is therefore already
   // zero. zeroedBase is relative to the arena base.
   // Increases monotonically until it hits heapArenaBytes.
   //
   // This field is sufficient to determine if an allocation
   // needs to be zeroed because the page allocator follows an
   // address-ordered first-fit policy.
   //
   // Read atomically and written with an atomic CAS.
   zeroedBase uintptr
}

本文链接地址:http://www.ysxbohui.com/article/237

正文到此结束