GO内存管理与分配

go的内存管理是由标准库自动完成的从内存管理到不再使用的情况,尽管开发人员不需要去处理它,go的底层管理经过了良好的优化并且充满了有趣的概念

go的内存分配器

相关结构为:

  fixalloc: 用于固定大小的堆外对象自由列表分配器
  mheap:内存堆,以页面8192粒度进行管理
  mspan:由mheap管理的一系列页面
  mcentral:手动给定大小类的所有跨度
  mcache:具有可用空间mspans每个P缓存
  mstats:分配统计信息

基本策略

1、每次从操作系统申请一大块的内存以减少系统调用
2、将申请到大块内存按照预先的切分成小块构成链表
3、为对象分配内存 只需要从大小合适的链表提取一个小块就可
4、回收帝乡内存时,将该小块内存重现归还到原链表,仪表复用
5、闲置内存过多把一部分内存给操作吸引,降低整体的开销

虚拟的内存布局

堆由一系列的arena组成,这些在64位上位64mb在32位位4mb每一个arena开始地址和他们的大小是对齐的。
每一个arena都有一个关联的heapArea对象,该对象存储一些元数据所有对象的堆位图
由于areana是对齐的,因此可以将地址视为一系列的areana帧,这些为一个地址,对于地址为nil的 不受go堆支持,arena map 为L1 map和L2
组成的两极数组。

堆上分配

go的内存管理被设计成非常快的在并发环境与垃圾收集器集成在一起。举个例子:

package main

type smallStruct struct {
   a, b int64
   c, d float64
}

func main() {
   smallAllocation()
}

//go:noinline
func smallAllocation() *smallStruct {
   return &smallStruct{}
}

这个go:noinline将不会被内联将通过删除函数来优化,因此,最终将不进行分配。
运行这个降本分析命令go tool compile "m" main.go 将会去验证go的分配模式

main.go:14:9: &smallStruct literal escapes to heap

由于go tool compile-s main.go,转储此程序的程序集代码还将显式显示分配:

0x001d 00029 (main.go:14)   LEAQ   type."".smallStruct(SB), AX
0x0024 00036 (main.go:14)  PCDATA $0, $0
0x0024 00036 (main.go:14)  MOVQ   AX, (SP)
0x0028 00040 (main.go:14)  CALL   runtime.newobject(SB)

newobject函数是用于新分配和代理mallocgc的内置函数,该函数在堆上管理这些分配和代理。Go中有两种策略,一种是针对小的分配,另一种是针对大的分配。

小分配

1、将变为小尺度类别之一,然后在p的mcachae中查找相应的mspan,扫描msapn的空闲插槽,分配它,可用在不获取锁的情况下完成
2、如果span没有可用的插槽,获取UI个新的msapn,会从mcentral所需大小的msapn列表中获取可用空间的类,得到整个跨度会分销锁定中心成本。
3、如果mcentral的mspan列表为空,获得一个centra来自mheap的页面
4、如果mheap卫康或没有足够大的页面圆形,将会从操作系统中分配一组页 至少是1mb, 去操作系统分配大量的页

对于32kb以下的小分配,go将尝试从名为mcache的本地缓存获取内存。此缓存处理一个名为mspan的SPAN列表,其中包含可用于分配的内存:


1_vM6qAEYPPNo901TbXRaMkw.png

每个线程m被分配给一个处理器p,并且一次最多处理一个goroutine。在分配内存时,我们当前的goroutine将使用其当前m的本地缓存来查找SPAN列表中的第一个可用对象。使用此本地缓存不需要锁定,并使分配更有效

span列表分为大约70个大小类,从8字节到32k字节,可以存储不同的对象大小:


1_DrCABMaTrikx-cr3Y8qxWQ.png

每个span存在两次:一个包含不包含指针的对象的列表,另一个包含指针。这种区别将使垃圾收集器的使用寿命变得更容易,因为它不必扫描不包含任何指针的范围
在我们前面的示例中,结构的大小为32字节,将适合32字节的范围


1_Wc3ITlMVvZyVu7osG4n_Pw (1).png

现在,我们可能想知道,如果在分配期间SPAN没有空闲插槽,会发生什么情况。go维护每个大小的跨度类(称为mcentral)的中心列表,其中包含自由对象的跨度和不包含自由对象的跨度:


1_FWwcHcL0sgmp9eaidCZiEQ (1).png

mcentral维护一个span双链表,每个span独有对上一个span和下一个span的引用,一个span在空的列表中的包含着一些已使用的内存。事实上,当垃圾收集器清理一部分内存时,它可以清理一部分空间,这些空间将被放回已清理这些空闲的空槽列表中
如果插槽用完,我们的程序现在可以从中央列表中请求一个span:


1_8addqzg5-8vRE4aKFkJ-ew (1).png

如果这个空的列表中没有可用的span,就需要去中心列表申请一个新的span,新的span将从堆中分配并链接到中心列表:


1_5k14MlKkyRxUi7pqW69EdQ.png

堆在需要时从操作系统中提取内存。如果需要更多的内存,堆将分配一大块称为arena的内存,64位体系结构为64MB,其他大部分体系结构为4MB。竞技场还将内存页映射为span:


1_3i6nEwjnHVdCnCIGBkzQFA.png

大分配

go不使用本地缓存管理大型分配。这些大于32KB的分配被舍入到页面大小,页面直接分配给堆。


1_3i6nEwjnHVdCnCIGBkzQFA.png

完整分配过程如下:


1_q9PZ3azdW--DY3SFpKlfBA.png

参考:https://medium.com/a-journey-with-go/go-memory-management-and-allocation-a7396d430f44

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容