Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can this type of golang string slicing leak memory in underlying byte array?

Can golang string slicing like buf = buf[n:] cause memory leak in the underlying byte array?

If so, is it possible to get any information (like capacity, or base memory address) about the underlying byte array, in order to verify the leak?

Please see sample code below:

var buf string

func push(s string) {
    buf += s
    if len(buf) > 3 {
        buf = buf[len(buf)-3:] // can this line leak memory in underlying byte array?
    }
    fmt.Printf("buf=[%v]\n", buf)
}

Run it on playground

like image 223
Everton Avatar asked Feb 08 '23 05:02

Everton


1 Answers

No, this example can't cause a memory leak, since you need to allocate new strings each time you call push. It's possible that some bytes will be kept around at times to reduce allocations, but how that works is an implementation detail that shouldn't be taken into consideration.

If you're thinking of a similar situation which can arise when you assign a result of a slice operation, but never append. There's no leak per say, as long as you understand the semantics of slicing.

s := make([]byte, 1024)
s = s[1000:]
fmt.Println(s, len(s), cap(s))

This example will leave the first 1000 bytes allocated, but inaccessible. The answer to this is simple, don't do that. It's not hard to avoid, and if you do need to ensure that you've released the underlying array, use copy to move the bytes to a new slice.

This works the same with strings:

s = s[1020:]
// may leave the first 1000 bytes allocated

This is again fairly easy to see what's going on, and avoid. If you're using huge strings, you're often better off using []byte anyway, where you have better control over allocation, and can copy the bytes when needed.

like image 98
JimB Avatar answered Feb 11 '23 02:02

JimB