英文:
Do Clearing slices in golang guarantees garbage collection?
问题
我想使用 Golang 切片实现基于时间的数据槽。我成功编写了以下类似的 Go 程序,并且它也能正常工作。但是我对于垃圾回收和程序的整体性能有一些疑问。当切片被赋值为 nil 时,这个程序是否保证对项目进行垃圾回收?在对切片进行洗牌时,我希望这个程序不进行深拷贝。
type DataSlots struct {
slotDuration int // 毫秒为单位
slots [][]interface{}
totalDuration int // 毫秒为单位
}
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)
}
// 这应该是一个 goroutine
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
}
}
我在这个代码片段中删除了关键部分的处理,以使其更简洁。
英文:
I wanted to implement time based slots for holding data using golang slices. I managed to come up with a go program like this and it also works. But I have few questions regarding garbage collection and the general performance of this program. Does this program guarantee garbage collection of items once slice is equated to nil? And while shuffling slices, I hope this program does not do any deep copying.
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
}
}
I removed critical section handling in this snippet to make it concise.
答案1
得分: 5
一旦将切片设置为nil
,则切片中包含的任何值都可以进行垃圾回收,前提是底层数组没有与另一个切片共享。
由于您的程序中没有切片操作,因此您永远不会有对同一数组的多个引用,也不会在底层数组的任何不可访问部分中留下数据。
您需要注意的是,在使用切片操作时:
a := []int{1, 2, 3, 4}
b := a[1:3]
a = nil
// 值1和4无法被回收,因为它们仍然包含在b的底层数组中
c := []int{1, 2, 3, 4}
c = append(c[1:2], 5)
// c现在是[]int{2, 5},但是值1和4仍然在底层数组中。4可能会被后续的append覆盖,但是1是不可访问的,直到底层数组被复制。
虽然append
在切片容量不足时会复制值,但只会复制切片中包含的值。没有对任何值进行深拷贝。
英文:
Once your slice is set too nil
, any values contained in the slice are available for garbage collection, provided that the underlying array isn't shared with another slice.
Since there are no slice operations in your program, you never have multiple references to the same array, nor are you leaving data in any inaccessible portions of the underlying array.
What you need to be careful of, is when you're using slice operations:
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.
While append
does copy values when the capacity of the slice in insufficient, only the values contained in the slice are copied. There is no deep copy of any of the values.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论