gc如何处理切片内存回收

问题描述 投票:-1回答:1
var a = [...]int{1,2,3,4,5,6}
s1 := a[2:4:5]

假设s1晚于a超出范围。 gc如何知道回收s1底层数组的内存?

考虑s1,spec的运行时表示

type SliceHeader struct {
        Data uintptr
        Len  int
        Cap  int
}

GC甚至不知道a的开头。

go garbage-collection slice
1个回答
1
投票

Go使用标记和扫描收集器作为它的当前实现。

根据算法,将有一个根对象,其余为树状结构,在多核机器的情况下,gc与一个核心上的程序一起运行。

gc将遍历树,当某些东西无法到达时,它会认为它是免费的。

Go对象还具有此post中所述的对象元数据。

摘录:

我们需要有关于对象的一些信息,因为我们没有标题。标记位保留在侧面并用于标记和分配。每个单词都有2位与之关联,以告诉您它是否是该单词中的标量或指针。它还编码了对象中是否有更多指针,因此我们可以尽早停止扫描对象。

原因是切片(切片头)是结构而不是指向结构的指针由russ cox在切片部分下的page中记录。

这是一段摘录:

Go最初表示一个切片作为指向结构的指针(切片头),但这样做意味着每个切片操作都分配了一个新的内存对象。即使使用快速分配器,也会为垃圾收集器创建大量不必要的工作,我们发现,与字符串的情况一样,程序避免了切片操作,有利于传递显式索引。删除间接和分配使得切片足够便宜,以避免在大多数情况下传递显式索引。

数组的大小(长度)是其类型的一部分。类型[1]int[2]int是不同的。

要记住的一件事是go是面向价值的语言,而不是存储指针,它们存储直接值。

[3]int,数组是go中的值,所以如果你传递一个数组,它会复制整个数组。 [3]int这是一个值(一个整体)。

当你做a[1]时,你正在访问部分价值。

SliceHeader数据字段表示将此视为数组的基点,而不是a[0]

据我所知,我认为:

当一个人请求a[4]时,

a[0]+(sizeof(type)*4)

计算。

现在,如果您通过切片s = a[2:4]访问某些内容,并且如果有人请求s[1],那么请求的是,

a[2]+sizeof(type)*1
© www.soinside.com 2019 - 2024. All rights reserved.