go 内存模型

大体上来说go的内存是先申请一大片内存,然后将内存分为各个小的span来管理,因为每个go对象有对应的对象大小,将会根据对象的大小放入不同span中。
细分来看go内存分配器包含内存管理单元、线程缓存、中心缓存和页堆几个重要组件, 分别对应的数据结构 mspan、 mcache、 mcentral、 mheap
mspan:
Go语言内存管理的基本单元,该结构体包含next和prev两个字段,分别指向了前一个和后一个的mspan;
串联后形成一个双向链表,mspanlist存储双向链表的头节点和尾节点并再mcache和mcentral中使用
mcache:
Go语言中的线程缓存,它会与线程上的处理器(GMP-P)绑定;
mcentral:
内存分配器的中心缓存,与线程缓存不同,访问中心缓存中的mspan需要使用互斥锁,每个mcentral都会管理某个spanclass的内存管理单元; 他会持有两个runtime.spanSet,分别存储包含空闲对象和不包含空闲对象的mspan。
mheap:
负责内存分配的核心组件,包含mcentral和heapArena,堆上所有mspan都是mheap结构分配来的
三个核心变量:
allspans: 已经分配的所有mspan
arenas: heapArena数组,用于管理一个个内存块
central: mcentral数组,用于管理对应spanClass的mspan
功能:
- 管理大对象
- 负责管理mcentral和heapAreana
- heapAreana负责管理空闲内存和向操作系统再申请内存。
总结:
- 大对象直接从mheap上分配;
- 小对象首先计算对象的规格大小,然后使用mcache中相应规格大小的mspan分配;
- 如果mcache没有相应规格大小的mspan,指向mcentral申请;
- 如果mcentral没有相应规格大小的mspan,指向mheap申请;
- 如果mheap没有相应规格大小的mspan,指向操作系统申请;
参考:
https://www.cntofu.com/book/3/zh/06.1.md
https://blog.csdn.net/weixin_46253576/article/details/124599571
https://cloud.tencent.com/developer/article/1476679?from=article.detail.1476473
网友评论