Unlike C/C++, Go has GC, so we don’t need to handle memory allocation/release. However, we also should be cautious about memory leak.
Today, let’s see a memory leak case caused by slice
.
package mainimport (
"fmt"
)type Object struct {}func main() {
var a []*Object
for i := 0; i < 8; i++ {
a = append(a, new(Object))
} fmt.Println(cap(a), len(a)) // Output: 8, 8 a = remove(a, 5) fmt.Println(cap(a), len(a)) // Output: 8, 7
}func remove(s []*Object, i int) []*Object {
return append(s[:i], s[i+1:]...)
}
Click https://play.golang.org/p/BxybSc5PDfF to run the example. We can notice the capacity of a
is still 8 even one object has been removed, which means function remove
may cause a potential memory leak.
Why would it happen?
As we know, every slice
has an underlying array
, an array
may be shared among several slices
. If the new slice’s length will exceed the array’s capacity, a new array will be created for the new slice. Usually new capacity will be two times old capacity. In another word, we can think slice
is a view of the part array, just like the relationship between view
and table
in database.
Let’s take a look at an example
package mainimport (
"fmt"
)