Golang内存分配
2023-01-31 16:31:54 0 举报
Golang内存分配
作者其他创作
大纲/内容
startAddr
有了管理内存的基本单位span,还要有个数据结构来管理span,这个数据结构叫mcentral,各线程需要内存时从mcentral管理的span中申请内存,为了避免多线程申请内存时不断的加锁,Golang为每个线程分配了span的缓存,这个缓存即是cache。src/runtime/mcache.go:mcache定义了cache的数据结构:type mcache struct { alloc [67*2]*mspan // 按class分组的mspan列表}
noscan
spanclass=10
bitmap
scan
s
512M
class66
page
编写过C语言程序的肯定知道通过malloc()方法动态申请内存,其中内存分配器使用的是glibc提供的ptmalloc2。 除了glibc,业界比较出名的内存分配器有Google的tcmalloc和Facebook的jemalloc。二者在避免内存碎片和性能上均比glic有比较大的优势,在多线程环境中效果更明显。Golang中也实现了内存分配器,原理与tcmalloc类似,简单的说就是维护一块大的全局内存,每个线程(Golang中为P)维护一块小的私有内存,私有内存不足再从全局申请。
central
class0
allocCount=2
class1
arena
512GB
font color=\"#ff0000\
16G
spans
nelems=56
cache作为线程的私有资源为单个线程服务,而central则是全局资源,为多个线程服务,当某个线程内存不足时会向central申请,当某个线程释放内存时又会回收进central。src/runtime/mcentral.go:mcentral定义了central数据结构:type mcentral struct { lock mutex //互斥锁 spanclass spanClass // span class ID nonempty mSpanList // non-empty 指还有空闲块的span列表 empty mSpanList // 指没有空闲块的span列表 nmalloc uint64 // 已累计分配的对象个数}lock: 线程间互斥锁,防止多线程读写冲突spanclass : 每个mcentral管理着一组有相同class的span列表nonempty: 指还有内存可用的span列表empty: 指没有内存可用的span列表nmalloc: 指累计分配的对象个数
arena_used
cache/central数据结构
span数据结构
mspan
mcache
arena_start
heap数据结构
mheap
lock
go 内存分配-64bit
mheap数据结构
arena=512Gpage=8KBarena页数=512G/8KBspans区域存放指针,每个指针对应一个pagespan=arena页数*指针大小(8B)=512Mbitmap区域大小也是通过arena计算出来,不过主要用于GCspans区域存放span的指针,span用于管理arena页的关键数据结构,每个span中包含1个或多个连续页,为了满足小对象分配,span中的一页会划分更小的粒度,而对于大对象比如超过页大小,则通过多页实现
allocBits
npages=1
elemsize=144
内存分配过程:Golang内存分配是个相当复杂的过程,其中还掺杂了GC的处理,这里仅仅对其关键数据结构进行了说明,了解其原理而又不至于深陷实现细节。Golang程序启动时申请一大块内存,并划分成spans、bitmap、arena区域arena区域按页划分成一个个小块span管理一个或多个页mcentral管理多个span供线程申请使用mcache作为线程私有资源,资源来源于mcentral
central[134]
alloc[134]
...
0 条评论
回复 删除
下一页