关于tiny的几个疑问

来源:1-13 Go 语言的内存管理与垃圾回收

weixin_慕设计2382076

2021-06-12 06:23:18

当需要的内存小于16 bytes && 没有包含指针的时候,内存分配的是tiny,基于这个前提,有几个疑问:

1、图中mcache里tiny指向的列表下面的64bytes是一个tiny elem,那么一个tiny对象最大16byte,岂不是访问alloc很频繁?

2、mcache中的alloc指向的列表,是不是和central一样甚至是同一个东西?

3、为什么说会tiny对象本地用完之后,都在第5个槽上找内存?如果说是没有指针,noscan放在奇数槽,那么1,3,5...分别对应的spanClass应该是8bytes、16bytes、32bytes?是不是我理解错了?


写回答

1回答

Xargin

2021-06-12

  1. 课上的图画的有点问题,槽是第5个,不过这个槽里的元素大小是 16 bytes,不是 64 bytes,ppt 已修复,槽内元素大小要用 sizeClass 算,而不是 spanClass,sizeClass = spanClass(5) >> 1 = 2,对应代码表格里的 class 2,也就是 16 bytes

  2. 本质上都是指向一块内存,只不过不同区域看待内存的角度不一样,所以有不同的结构,mcache 里的 134 个槽,每个槽里只有一个 mspan,而 mcentral 里的那 134 个槽,每个槽是一个 mspan 的列表(当然他还分了 empty 和 non-empty)。列表里的元素是从 central 被分配到 mcache 里的,除了 large 的分配,其它都是一级一级向上申请,向下下发。同一个 spanClass 的 mspan 结构上是完全一样的,不管他是在 mcentral 还是在 mcache 里。

  3. 0 和 1 号槽是给 large 预留的,2-3 号槽是给 <= 8 字节的做分配,4-5 号槽是给 <=16 字节的做分配。只不过 5 号还会被用来给 tiny 类型的做分配。

5 号槽是这么算出来的:


type spanClass uint8
tinySpanClass = spanClass(tinySizeClass<<1 | 1)
​tinySizeClass = _TinySizeClass
​_TinySizeClass = int8(2)


2 << 1 | 1 = 5

1

Go高级工程师实战营

慕课网与 GoCN 社区官方联手打造,定义行业Go高级人才培养标准,4个月,快速晋升为P6+/D7级高级人才。

458 学习 · 266 问题

查看课程