Do Clearing slices in golang guarantees garbage collection?

谁都会走 提交于 2019-12-10 15:40:01

问题


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:


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.




回答2:


Does this program guarantee garbage collection of items once slice is equated to nil ?

At some point yes, but not right away.

But try to speed up the collection with:

import "runtime/debug"

...

debug.FreeOSMemory()

https://golang.org/pkg/runtime/debug/#FreeOSMemory

func FreeOSMemory()

FreeOSMemory forces a garbage collection followed by an attempt to return as much memory to the operating system as possible. (Even if this is not called, the runtime gradually returns memory to the operating system in a background task.)



来源:https://stackoverflow.com/questions/33385664/do-clearing-slices-in-golang-guarantees-garbage-collection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!