栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

去垃圾会收集切片的一部分吗?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

去垃圾会收集切片的一部分吗?

切片只是描述符(类似于小型结构的数据结构),如果不对其进行引用,则会对其进行正确的垃圾回收。

另一方面,切片的基本数组(描述符指向该数组)在所有切片之间 共享 ,这些切片通过切片来 共享 :引用自Go语言规范:Slice
Types

切片一旦初始化,便始终与包含其元素的基础数组关联。因此,一个片与其阵列以及同一阵列的其他片共享存储。相反,不同的数组始终代表不同的存储。

因此,如果存在至少一个片,或保存数组的变量(如果通过对数组进行切片来创建片),则不会进行垃圾回收。

关于此的官方声明:

安德鲁·格朗德(Andrew Gerrand)撰写的博客文章 Go
Slices:用法和内部

原理明确说明了这种行为:

如前所述,对切片进行重新切片不会复制基础数组。 完整的数组将保留在内存中,直到不再被引用为止。
有时,这可能导致程序仅需要一小部分数据时就将所有数据保存在内存中。

由于切片引用了原始数组, 因此只要将切片保留在垃圾收集器周围,就无法释放该数组

回到你的例子

虽然基础数组不会被释放,但是请注意,如果您将新元素添加到队列中,则内置

append
函数有时可能会分配新数组并将当前元素复制到新元素上,但是复制只会复制切片的元素而不是整个基础数组!当发生这种重新分配和复制时,如果没有其他引用,则可能会“回收”旧数组。

另一个非常重要的事情是,如果从前面弹出一个元素,则切片将被切片并且不包含对弹出元素的引用,但是由于基础数组仍包含该值,因此该值也将保留在内存中(而不是只是数组)。建议每当从队列(切片/数组)中弹出或删除一个元素时,
始终将其 (切片中其相应的元素) 置零, 这样该值就不会不必要地保留在内存中。如果您的分片包含指向大数据结构的指针,则这一点变得尤为重要。

func PopFront(q *[]string) string {    r := (*q)[0]    (*q)[0] = ""  // Always zero the removed element!    *q = (*q)[1:len(*q)]    return r}

这里提到了Slice Tricks
Wiki页面:

删除但不保留订单

a[i] = a[len(a)-1]a = a[:len(a)-1]

注意 如果元素的类型是一个 指针 或指针字段,其需要被垃圾收集一个结构,上述实施方式

Cut
Delete
有潜在的 存储器泄露
的问题:其值的一些元素仍然由切片引用
a
并因此不能集。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/471069.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号