GO内存简介 | 青训营笔记

82 阅读2分钟

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

GO内存分配

GO程序在启动的时候向操作系统申请一个内存,将申请到的内存分配为三个大区域512MB,16GB,512GB。

arena就是堆区,对象动态分配内存的地方,按8KB拆分成页,多个页构成一个mspan。

左边低地址,右边高地址

bitmap的大小有arena决定的,bitmap用于标识area区域中一个byte对应arena中的4个指针(指针大小8B),所以bitmap大小为512GB/(4*8B)=16GB.

bitmap和arena紧靠,arena由低地址向高地址生长,bitmap的地址是由高地址向低地址增长的。

spans区域存放指针,指针指向mspan,mspan最小就是一页8k,一个指针8B,所以spans的大小为512GB/8KB*8B=512MB。那么什么是mspan呢?

mspan:

也就是内存分块。将arena分成很多块。

Go中内存管理的基本单元,是由一片连续的8KB的页组成的大块内存。mspan是双端链表的结点。mspan中存放object,根据每种object的大小不同,又可以给mspan分为很多类,object大小相近的放在一起,大对象的存储可以在堆上直接分配。

mcache:

每个goroutine都会有一块缓存。可以解决Gorouine之间的竞争问题,不会消耗锁资源,

mcentral:

mcentral被所有的工作线程共同享有,存在多个Goroutine竞争的情况,因此会消耗锁资源。

mheap

mheap:代表Go程序持有的所有堆空间,Go程序使用一个mheap的全局对象_mheap来管理堆内存。

线上生成很多小对象,分配内存耗时,

字节跳动给每个g(goroutine)分配一个GAB,类似于java的给线程预分配一个空间。GAB类似于一个大对象。

GAB有点像Java的G1垃圾收集器。

总结:

内存分配是一个复杂问题,GO程序启动会申请一大块内存,然后又成三个大块,然后又是mspan小块,mcache, mcentral, mheap是Go内存管理的三大组件,层层递进。小对象和大对象的分配比较特殊。

参考:

juejin.cn/post/684490…