Go 内存管理 & 编译器优化思路| 青训营笔记

41 阅读1分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 7 天


Go 内存管理 & 编译器优化思路

目标:为对象在heap上分配内存 提前将内存分块 调用系统调用map()向OS申请一大块内存,例如4MB 先将内存划分成大块,例如8KB称作 span 再将大块继续划分成特定大小的小块,用于对象分配 noscan span:分配不包含指针的对象-一GC不需要描 scan span:分配包含指针的对象一GC需要扫描 对象分配:根据对象的大小,选择最合适的块返回

Tcmalloc: thread caching 每个p包含一个 mcache用于快速分配,用于为绑定 于p上的g分配对象 mcache管理一组 span 当 mcache中的 span分配完毕,向 central申 请带有末分配块的 span 当 span中没有分配的对象, span会被缓存在 central中,而不是立刻释放井归还给OS

对象分配是非常高频的操作:每秒分配GB级别的内存 小对象占比较高 Go内存分配比较耗时 分配路径长:9->m->p-> mcache-> span-> memory block-> return pointer pprof:对象分配的函数是最频繁调用的函数之

每个g都绑定一大块内存(1KB),称作 goroutine allocation buffer(GAB) GAB用于 oscar类型的小对象分配:<128B 使用三个指针维护GAB:base,end,top Bump pointer(指针碰撞)风格对象分配 无须和其他分配请求互斥 分配动作简单高效