重新切片和垃圾回收

huangapple go评论89阅读模式
英文:

Re-slicing and garbage collection

问题

当重新切片时,是否需要将不再在切片中的元素设置为nil?这对垃圾回收有什么影响吗?

type X struct {
  Value   string
}

func main() {
    Xs := []*X{&X{"a"}, &X{"b"}, &X{"c"}, &X{"d"}}
    X0 := Xs[0]
    Xs[0] = nil //这行代码对垃圾回收器有任何影响吗?是否必要?
    Xs = Xs[1:]
}

更新

strings := []string{"a", "b", "c", "d"}
string0 := strings[0]
//如何将strings[0]置零?
strings = strings[1:]
英文:

When re-slicing, do i need to set the elements that are not in the slice anymore to nil,does it have any effect on garbage collection?

type X struct {
  Value   string
}

func main() {
	Xs:=[]*X{&X{"a"},&X{"b"},&X{"c"},&X{"d"}}
	X0:= Xs[0]
    Xs[0] = nil //does this line has any effect on the garbage collector,is it necessary?
	Xs= Xs[1:]
}

Update:

strings:=[]string{"a","b","c","d"}
string0:= strings[0]
//how do i zero strings[0]?
strings = strings[1:]

答案1

得分: 4

简短回答:是的。

在重新切片一个切片或数组后,新切片中不可见的元素不会自动清零。由于支持数组仍然保存在内存中,所以其中存储的元素也会保留在内存中。

更多详细信息请参见此答案。引用相关部分:

> 还有一个非常重要的事情是,如果从前面弹出一个元素,切片将被重新切片,并且不包含对弹出元素的引用,但由于底层数组仍然包含该值,该值也将保留在内存中(不仅仅是数组)。建议在从队列(切片/数组)中弹出或删除元素时,始终将其清零(在切片中的相应元素)。这在切片包含指向大型数据结构的指针时尤为重要。

更新:

可以通过以下方式将您的更新代码清零:

strings:=[]string{"a","b","c","d"}
// 重要:在重新切片之前清零:
strings[0] = "" // 空字符串是string的零值
strings = strings[1:]

注意:复制元素并将其清零不会清零数组中的值,因此这没有任何效果:

strings:=[]string{"a","b","c","d"}
string0:= strings[0]
strings = strings[1:]

// 这对数组没有影响,它只是将变量string0清零
string0 = ""
英文:

Short answer: yes.

After reslicing a slice or array, elements that are not visible in the new slice are not zeroed automatically. And since the backing array is kept in memory, so are the elements stored in them.

See this answer for more details. Quoting the relevant part:

> Also another very important thing is that if an element is popped from the front, the slice will be resliced and not contain a reference to the popped element, but since the underlying array still contains that value, the value will also remain in memory (not just the array). It is recommended that whenever an element is popped or removed from your queue (slice/array), always zero it (its respective element in the slice) so the value will not remain in memory needlessly. This becomes even more critical if your slice contains pointers to big data structures.

Update:

Your updated code could be zeroed this way:

strings:=[]string{"a","b","c","d"}
// IMPORTANT: zero before reslicing:
strings[0] = "" // Empty string is the zero value of string
strings = strings[1:]

Note: Making a copy of the element(s) and zeroing them does not zero the values in array, so this has no effect:

strings:=[]string{"a","b","c","d"}
string0:= strings[0]
strings = strings[1:]

// This has no effect on the array, it just zeroes the variable string0
string0 = ""

huangapple
  • 本文由 发表于 2015年3月3日 20:38:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/28832016.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定