go里面的垃圾回收是如何进行的(2)?
学习好一门语言贵在坚持!
首先:
博主是👦一个帅气的boy,你可以叫我山鱼君
🖱 ⌨个人主页:山鱼君的个人主页
💖💖如果对你有帮助的话希望三连下⭐⭐⭐支持一下博主🌊
精确的垃圾回收
像C语言这种不支持垃圾回收的语言,其实还是有些垃圾回收的库可以使用的。这类库一般也是用的标记清扫算法实现的,但是它们都是保守的垃圾回收。之所以叫“保守”是因为它们没办法获取对象类型信息,因此只能保守地假设地址区间中每个字都是指针。
无法获取对象的类型信息会造成什么问题呢?这里举个例子来说明。
假设某个结构体中是不包含指针成员的,那么对该结构体成员进行垃圾回收时,其实是不必要递归地标记结构体的成员的。但是由于没有类型信息,我们并不知道这个结构体成员不包含指针,因此我们只能对结构体的每个字节递归地标记下去,这显然会浪费很多时间。这个例子说明精确的垃圾回收可以减少不必要的扫描,提高标记过程的速度。 这个例子说明,保守的垃圾回收某些情况下会出现垃圾无法被回收的情况。虽然不会造成大的问题,但总是让人很不爽,都是没有类型信息惹的祸。 现在好了,在Go语言的 1.1 版本中开始支持精确的垃圾回收。精确的垃圾回收首先需要的就是类型信息,上一节中讲过 MSpan 结构体,类型信息是存储在 MSpan 中的。从一个地址计算它所属的 MSpan,公式如下:
页号 = (地址 - mheap.arena_start) >> 页大小
MSpan = mheap->map[页号]
1.接下来通过 MSpan->type 可以得到分配块的类型。这是一个 MType 的结构体:
struct MTypes
{
byte compression; // one of MTypes_*
bool sysalloc; // whether (void*)data is from runtime·SysAlloc uintptr data;
}; 2.MTypes
MTypes 描述 MSpan 里分配的块的类型,其中 compression 域描述数据的布局。它的取值为 MTypes_Empty、MTypes_Single、MTypes_Words、MTypes_Bytes 四个中的一种:
MTypes_Empty:所有的块都是 free 的,或者这个分配块的类型信息不可用。这种情况下 data 域是无意义的。
MTypes_Single:这个 MSpan 只包含一个块,data 域存放类型信息,sysalloc 域无意义。
MTypes_Words:这个 MSpan 包含多个块(块的种类多于 7)。这时 data 指向一个数组 [NumBlocks]uintptr,数组里每个元索存放相应块的类型信息。
MTypes_Bytes:这个 MSpan 中包含最多 7 种不同类型的块。这时 data 域指下面这个结构体
struct {
type [8]uintptr // type[0] is always 0
index [NumBlocks]byte
} 第 i 个块的类型是 data.type[data.index[i]]
表面上看 MTypes_Bytes 好像最复杂,其实这里的复杂程度是 MTypes_Empty 小于 MTypes_Single 小于 MTypes_Bytes 小于 MTypes_Words 的。MTypes_Bytes 只不过为了做优化而显得很复杂。
上一节中说过,每一块 MSpan 中存放的块的大小都是一样的,不过它们的类型不一定相同。如果没有使用,那么这个 MSpan 的类型就是 MTypes_Empty。如果存一个很大块,大于这个 MSpan 大小的一半,因此存不了其它东西了,那么这个 MSpan 的类型是 MTypes_Single。
假设存了多种块,每一块用一个指针,本来可以直接用 MTypes_Words 存的。但是当类型不多时,可以把这些类型的指针集中起来放在数组中,然后存储数组索引。这是一个小的优化,可以节省内存空间。
得到的类型信息最终其实是一个这样的结构体:
struct Type
{
uintptr size;
uint32 hash;
uint8 _unused;
uint8 align;
uint8 fieldAlign;
uint8 kind;
Alg *alg;
void *gc;
String *string;
UncommonType *x;
Type *ptrto;
}; 不同类型的类型信息结构体略有不同,这个是通用的部分。可以看到这个结构体中有一个 gc 域,精确的垃圾回收就是利用类型信息中这个 gc 域实现的。
#go语言##快乐学习#最后:
✨原 创 不 易 , 还 希 望 各 位 大 佬 支 持 一 下 原创不易,还希望各位大佬支持一下
点赞👍:您的赞赏是我前进的动力!
收藏⭐:您的支持我是创作的源泉!
评论✍:您的建议是我改进的良药!
查看1道真题和解析
