清除golang中的切片是否可以保证垃圾收集?

use*_*780 4 garbage-collection go slice

我想实现基于时间的插槽,以便使用golang切片保存数据。我设法提出了一个go程序,它也可以工作。但是我对垃圾回收和该程序的一般性能没有疑问。切片等于nil时,此程序是否保证对项目进行垃圾回收?而且,在重新整理切片时,希望该程序不要进行任何深层复制。

type DataSlots struct {
    slotDuration  int //in milliseconds
    slots         [][]interface{}
    totalDuration int //in milliseconds
}

func New(slotDur int, totalDur int) *DataSlots {
    dat := &DataSlots{slotDuration: slotDur,
        totalDuration: totalDur}
    n := totalDur / slotDur
    dat.slots = make([][]interface{}, n)
    for i := 0; i < n; i++ {
        dat.slots[i] = make([]interface{}, 0)
    }
    go dat.manageSlots()
    return dat
}

func (self *DataSlots) addData(data interface{}) {
    self.slots[0] = append(self.slots[0], data)
}

// This should be a go routine
func (self *DataSlots) manageSlots() {
    n := self.totalDuration / self.slotDuration
    for {
        time.Sleep(time.Duration(self.slotDuration) * time.Millisecond)
        for i := n - 1; i > 0; i-- {
            self.slots[i] = self.slots[i-1]
        }
        self.slots[0] = nil
    }
}
Run Code Online (Sandbox Code Playgroud)

为了使内容简洁,我删除了此片段中的关键部分处理。

Jim*_*imB 5

一旦设置nil了切片,只要基础数组不与另一个切片共享,切片中包含的任何值都可用于垃圾回收。

由于程序中没有切片操作,因此您永远不会对同一个数组有多个引用,也不会将数据保留在基础数组的任何不可访问的部分中。

您需要注意的是使用切片操作时:

a := []int{1, 2, 3, 4}
b := a[1:3]
a = nil
// the values 1 and 4 can't be collected, because they are
// still contained in b's underlying array

c := []int{1, 2, 3, 4}
c = append(c[1:2], 5)
// c is now []int{2, 5}, but again the values 1 and 4 are
// still in the underlying array. The 4 may be overwritten
// by a later append, but the 1 is inaccessible and won't
// be collected until the underlying array is copied.
Run Code Online (Sandbox Code Playgroud)

虽然append在切片的容量不足时会复制值,但是仅复制切片中包含的值。没有任何值的深层副本。