mspan简介
Go中内存管理的基本单元,是由一片连续的 8KB的页组成的大块内存。注意,这里的页和操作系统本身的页并不是一回事,它一般是操作系统页大小的几倍。一句话概括: mspan是一个包含起始地址、 mspan规格、页的数量等内容的双端链表。
关于span的状态:
关于mspan的状态转换:
当mspan在堆的空闲treap(详情见备注)上,它的状态为mSpanFree
当mspan在清除treap上,当且仅当此时,scavengedtrue,其他所有情况该变量为false
当mspan是被使用的,它的状态为mSpanInUse,或者mSpanManual
1.span将从free到in-use或者manual在GC的任何阶段
2.在清除阶段gcphase_GCoff,span可以从in-use或者manual到free,in-use的转变对应的是清除,manual的转变对应的是堆栈被释放。
3.在整个gc,gcphase!=_GCoff,span不可以从manual或者in-use到free。因为当前GC读取指针并遍历它的span,span的状态必须保持单调。
mspan的图
mspan中allbits记录着哪些元素是已分配的,哪些未分配。alloccache用数字按位代表freeindex开始的
源码分析
1.mspanlist
//表示span的列表
//go:notinheap
type mSpanList struct {
first *mspan // first span in list, or nil if none
last *mspan // last span in list, or nil if none
}
2.mspan
type mspan struct {
//指向下一个span的指针
next *mspan
//指向上一个span的指针
prev *mspan
list