go内存管理机制
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
golang内存管理基本是参考tcmalloc来进行的。go内存管理本质上是一个内存池只不过内部做了很多优化自动伸缩内存池大小合理切割内存块。
基本概念
Page页一块 8 K大小的内存空间。Go向操作系统申请和释放内存都是以页为单位。
span内存块一个或多个page组成一个span。如果把page比喻成工人span可以看成是小队工人被分成若干个队伍不同的队伍干不同的活。
sizeclass空间规格每个span都带有一个sizeclass标记着该span中的 page 应该如何使用。使用上面的比喻就是sizeclass标志着 span 是一个什么样的队伍。
object对象用来存储一个变量数据内存空间一个span在初始化时会被切割成一堆等大的object。假设object的大小是 16Bspan大小是 8K那么就会把 span 中的 page 共初始化为 8k/16B = 512 个 object。所谓内存分配就是分配一个object出去。
mheap
一开始 go从操作系统索取一大块内存作为内存池并放在一个叫mheap的内存池进行管理mheap将一整块内存切割为不同的区域并将每一部分内存切割为合适的大小。
mheaps.spans用来存储 page 和 span 信息比如每一个 span 的起始地址是多少有几个 page 已使用了多少page等等
mheap.bitmap保存arena对应的某个地址是否存在对象以及对象是否被gc扫描过主要用于gc
mheap.arena_start将要分配给应用程序使用的空间由一个个page组成。
mcentral
用途相同的 span 会以链表的形式组织在一起存放在 mcentral 中。这里用途用sizeclass来表示就是该 span 存储到哪种大小的对象。
找到合适的 span 后会从中取出一个 object 返回给上层使用
mcache
为了提高内存并发申请效率加入缓存层mcache。每一个mcache和处理器P对应。Go申请内存首先从P的mcache中分配如果没有可用的span再从mcentral中获取。