go - gc如何处理slice内存回收

标签 go garbage-collection slice

var a = [...]int{1,2,3,4,5,6}
s1 := a[2:4:5]

假设 s1 比 a 超出范围。 gc是怎么知道回收s1底层数组a的内存的?

考虑 s1 的运行时表示,spec

type SliceHeader struct {
        Data uintptr
        Len  int
        Cap  int
}

GC 甚至不知道 a 的开始。

最佳答案

Go 在当前实现中使用标记清除收集器。

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

gc 将遍历树,当某物无法到达时,将其视为空闲。

Go 对象也有对象的元数据,如 post 中所述.

节选:

We needed to have some information about the objects since we didn't have headers. Mark bits are kept on the side and used for marking as well as allocation. Each word has 2 bits associated with it to tell you if it was a scalar or a pointer inside that word. It also encoded whether there were more pointers in the object so we could stop scanning objects sooner than later.

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

这是节选:

Go originally represented a slice as a pointer to the structure(slice header) , but doing so meant that every slice operation allocated a new memory object. Even with a fast allocator, that creates a lot of unnecessary work for the garbage collector, and we found that, as was the case with strings, programs avoided slicing operations in favor of passing explicit indices. Removing the indirection and the allocation made slices cheap enough to avoid passing explicit indices in most cases.

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

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

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

当执行 a[1] 时,您正在访问部分值。

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

据我所知:

当请求a[4]时,

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

是计算出来的。

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

a[2]+sizeof(type)*1

关于go - gc如何处理slice内存回收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52126085/

相关文章:

arrays - 如何在golang中找到两个 slice 的截距结果

c# - 包含对象实例的静态方法,错了吗?

java - jstat:OGC & OC、PGC & PC 的区别

go - 如何仅保留 slice 的最后20个元素

python - NumPy 。如何将二维数组按网格分割为多个数组?

sqlite - GORM 关联 .Create()

go - 可以将 golang channel 绑定(bind)到模板中

windows - Golang fmt.Print ("\033c") 和 fmt.Print ("\x1bc") 没有清除屏幕(ANSI Escape 代码不起作用)如何修复?

java - 是否可以创建堆转储来分析没有垃圾收集的内存泄漏?

python - 根据 x 个其他数组对 numpy 数组进行切片