* Tomi Häsä <
tomi...@gmail.com> [170110 02:23]:
I'm not sure if these were mentioned earlier in the thread, but both
https://blog.golang.org/slices and
https://blog.golang.org/go-slices-usage-and-internals give some really
good info on this.
The abbreviated answer is to think of a slice as a view into its backing
array. As long as a slice (or other variable) refers to the backing
array or one of its elements, the garbage collector will not reclaim any
of the backing array. So, even doing
group = group[1:]
will not allow the GC to reclaim the memory for the old group[0].
If the elements of the slice (and therefore of the backing array) are
simple values, such as ints, or structs of simple values, doing
group = group[:0]
will reset the slice to empty without changing its current capacity and
without reallocating the memory for its backing array.
If, however, the slice elements contain pointers, maps, channels, or
other slices, then the memory referred to by those items will not be
reclaimed, even though group appears to not refer to them. As you
append to group the second time around, those elements will be
overwritten, and the memory referred to by the old values will be able
to be reclaimed by the GC. Example:
type LargeStruct struct { /* lots of fields */ }
func NewLargeStruct(i int) (ls *LargeStruct) { /* does what's needed */ }
type SmallStruct struct { ls *LargeStruct }
var small []SmallStruct = make([]SmallStruct, 0, 50)
for i := 0; i < 10; i++ {
small = append(small, SmallStruct{NewLargeStruct(i)})
}
small[:0]
small is now an empty slice with capacity 50, but none of the memory
allocated for the ten instances of LargeStruct is able to be reclaimed
by the GC. This is because the backing array still contains the
pointers to all of the LargeStruct's allocated in the loop. Now do
small = append(small, SmallStruct{NewLargeStruct(41)})
small = append(small, SmallStruct{NewLargeStruct(42)})
and the memory allocated by NewLargeStruct(0) and NewLargeStruct(1) in
the earlier loop can be reclaimed (assuming they are not referenced
elsewhere).
On the other hand, replacing
small[:0]
in the above code by
small = make([]SmallStruct, 0, 50)
will allocate a new backing array and will allow the old backing array
as well as all of the LargeStruct's to be reclaimed. Which is better
will depend on your application.
...Marvin