slice tails don't grow forever
In a garbage collected language, one needs to be cautious about leaks caused by errant references, but caution can turn to paranoia. In go, I like to make little fifo queues by appending to the tail of a slice. But does this grow forever?
s = append(s[1:], n)
One theory is that this will eventually consume all memory, as somehow the slice grows and grows. The garbage collector is unable to reduce its size because the head of the slice is still out there somewhere.
Another theory is no, the slice gets reallocated when it needs to expand, but only the referenced section gets copied.
We can test this!
package main
import (
"fmt"
"math/rand"
)
func main() {
var s []int
grow := false
for i := 0; i < 10000000000; i++ {
n := rand.Int()
if grow || len(s) < 100 {
s = append(s, n)
} else {
s = append(s[1:], n)
}
}
fmt.Printf("%v\n", s)
}
This runs basically forever, but uses very little memory. Changing grow to true, it reliably explodes.
I knew this, and was already relying on it, but also in most cases a slow leak may take weeks to develop and go unnoticed. Thirty seconds to check.