我想使用golang切片实现基于时间的插槽来保存数据。我设法提出了这样的go程序,它也有效。但我对垃圾收集和该程序的一般性能几乎没有疑问。切片等于零时,此程序是否保证项目的垃圾收集?虽然洗牌,我希望这个程序不会进行任何深度复制。
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
}
}
我删除了此代码段中的关键部分处理,以使其简洁。
答案 0 :(得分: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.
当切片的容量不足时,append
会复制值,而只复制切片中包含的值。没有任何值的深层副本。
答案 1 :(得分:-1)
此程序是否保证切片一旦进行垃圾收集 等于零?
在某些时候是,但不是马上。
但尝试用以下方法加快收集:
import "runtime/debug"
...
debug.FreeOSMemory()
https://golang.org/pkg/runtime/debug/#FreeOSMemory
func FreeOSMemory()
FreeOSMemory强制进行垃圾收集 尝试将尽可能多的内存返回给操作系统 可能。 (即使没有调用它,运行时也会逐渐返回 内存到后台任务中的操作系统。)