重新切片和垃圾收集

时间:2015-03-03 12:38:42

标签: go garbage-collection slice

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

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:]
}

更新

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

1 个答案:

答案 0 :(得分:4)

简答:是的。

重新切片或数组后,新切片中不可见的元素不会自动归零。由于支持数组保存在内存中,因此存储在其中的元素也是如此。

有关详细信息,请参阅this answer。引用相关部分:

  

另一个非常重要的事情是,如果从前面弹出一个元素,那么切片将被重新复制并且不包含对弹出元素的引用,但由于底层数组仍包含该值,因此该值也将保留在内存(不仅仅是数组)。建议无论何时从队列中弹出或删除元素(切片/数组),始终为零(它在切片中的相应元素),因此该值将不会不必要地保留在内存中。如果切片包含指向大数据结构的指针,这就变得更加重要。

<强>更新

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

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

注意:复制元素并将它们归零不会将数组中的值归零,所以这没有效果:

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 = ""