详解Go的内存分配机制

go的内存分配器就是维护一块大的全局内存,每个线程(go中为P)维护一块小的私有内存,私有内存不足再从全局申请。

1 基础概念

做法是:先向系统申请一块内存,然后将内存切割成小块,通过一定的内存分配算法管理内存。以64为系统为例,Golang程序启动时会向系统申请的内存如下图所示:

image-20240809215404808

预申请的内存划分为spans、bitmap、arena三部分。其中arena即为所谓的堆区,应用中需要的内存从这里分配。其中spans和bitmap是为了管理arena区而存在的。

  • arena的大小为512G,为了方便管理把arena区域划分成一个个的page,每个page为8KB,一共有512GB/8KB个页

  • spans区域存放span的指针,每个指针对应一个page,所以span区域的大小为(512GB/8KB)*指针大小8byte= 512M

  • bitmap区域大小也是通过arena计算出来,不过主要用于GC

2 span

span是用于管理arena页的关键数据结构,每个span中包含1个或多个连续页,为了满足小对象分配,span中的一页 会划分更小的粒度,而对于大对象比如超过页大小,则通过多页实现

2.1 class

根据对象大小,划分了一系列class,每个class都代表一个固定大小的对象,以及每个span的大小。如下表所示

//	class		bytes/obj		bytes/span		objects		waste bytes
//	1		      8				  8192			1024			0
//	2		      16			  8192			512		    	0
//	3		      32			  8192			256				0
//	4		      48			  8192			170				0
//	5		      64			  8192			128				0
//	6		      80			  8192			102				0
//	7		      96			  8192			85				0
//	8		      112			  8192			73				0
  • class:class ID,每个span结构中都有一个class ID, 表示该span可处理的对象类型
  • bytes/obj:该class代表对象的字节数
  • bytes/span:每个span占用堆的字节数,也即页数*页大小
  • objects:每个span可分配的对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值