ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Go 内存分配与分配器:mcache / mcentral / mheap 全解

Go 内存分配与分配器:mcache / mcentral / mheap 全解 Go 内存分配与分配器mcache / mcentral / mheap 全解Go 内存分配的三巨头是怎么配合工作的为什么大对象会直接走 mheap本篇从源码角度讲透。一、Go 内存分配层次mcache (per-P) → mcentral (global) → mheap (OS)每层负责不同对象大小。二、Span 与 Object classconst(_tinySizeClass16_smallSizeClass32*1024)Span 一段连续的 8KB 页多页合并。三、对象 size class对象分三类微小1-16 byte小对象16 byte-32 KB大对象32 KB每个 size class 都对应专门的 span。四、mcachetypemcachestruct{alloc[sizeClasses]unsafe.Pointer}每 P 一个 mcache无需加锁。从 alloc 数组取 span / object。五、mcentraltypemcentralstruct{nonempty partial empty partial}当 P 的 mcache 满了去对应的 mcentral 申请。六、mheaptypemheapstruct{spans[]mspan bitmap[]arena 堆区域}mheap 管理 arena。arena 起始地址_heapArenaStart。七、内存分配路径// micropackagemainimportunsafevarpmake([]byte,8)P 的 mcache 查找 size class (8 → class 1)mcache 分配中自由列表span.freelist取对象地址清零 返回八、大对象分配varpmake([]byte,32769)// 32KB 走 mheapmheap 直接 _heapAlloc - syscall 申请 mmap。九、释放路径对象释放时微小放回 P 的 mcache span小对象放回 mcentral大对象放回 mheap十、调优技巧GOGC与GOMEMLIMITdebug.SetGCPercent(200)debug.SetMemoryLimit(230)控制 GC 触发避免容器 OOM。十一、debug/elfmem pprofimportruntime/debugdebug.WriteHeapDump(...)抓取 heap dump。十二、踩坑清单大对象反复创建 32KB变 mheap 高频 mmap性能急降微对象分配可通过 size class 合并减少mheap 占据 mmap sys:受 ulimit 限制十三、对应 pprof 实测runtime.MemStats{}varm runtime.MemStats runtime.ReadMemStats(m)fmt.Println(m.HeapAlloc)十四、总结与展望掌握 mcache / mcentral / mheap 三层结构有助于排查内存问题。未来Go 仍在大对象快速分配 减少 GC 压力方向演进。1.22 已经引入对象预制。十五、参考文献runtime/mspan.goruntime/mcache.goruntime/mgc.go
返回列表