【问题标题】:Re-slicing and garbage collection重新切片和垃圾收集
【发布时间】:2015-03-03 12:38:42
【问题描述】:

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

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

【问题讨论】:

  • 很遗憾,是的。也许这会在 Go 语言的未来版本中得到改进。

标签: go garbage-collection slice


【解决方案1】:

简短回答:是的。

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

请参阅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 = ""

【讨论】:

  • 如果是一段字符串怎么办?,我只需要将它设置为空字符串吗?
  • @FPGA 那么string元素的值会保留在内存中并消耗内存。
  • 那么在这种情况下我应该把它变成一个指向字符串的指针的片段?
  • @FPGA 不,你不应该。我的意思是,如果您不将元素归零,那么它们将继续占用内存。您可以像这样将string 元素归零:lines[0] = ""(空字符串是string 的零元素)。
  • @FPGA 是的,如果没有其他参考的话。
猜你喜欢
  • 2018-10-05
  • 1970-01-01
  • 2015-04-10
  • 2014-02-23
  • 2012-03-21
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多