Does go garbage collect parts of slices?

前端 未结 4 1301
名媛妹妹
名媛妹妹 2020-12-03 03:17

If I implement a queue like this...

package main

import(
    \"fmt\"
)

func PopFront(q *[]string) string {
    r := (*q)[0]
    *q = (*q)[1:len(*q)]
    re         


        
4条回答
  •  离开以前
    2020-12-03 03:54

    No. At the time of this writing, the Go garbage collector (GC) is not smart enough to collect the beginning of an underlying array in a slice, even if it is inaccessible.

    As mentioned by others here, a slice (under the hood) is a struct of exactly three things: a pointer to its underlying array, the length of the slice (values accessible without reslicing), and the capacity of the slice (values accessible by reslicing). On the Go blog, slice internals are discussed at length. Here is another article I like about Go memory layouts.

    When you reslice and cut off the tail end of a slice, it is obvious (upon understanding the internals) that the underlying array, the pointer to the underlying array, and the slice's capacity are all left unchanged; only the slice length field is updated. When you re-slice and cut off the beginning of a slice, you are really changing the pointer to the underlying array along with the length and capacity. In this case, it is generally unclear (based on my readings) why the GC does not clean up this inaccessible part of the underlying array because you cannot re-slice the array to access it again. My assumption is that the underlying array is treated as one block of memory from the GC's point of view. If you can point to any part of the underlying array, the entire thing is ineligible for deallocation.

    I know what you're thinking... like the true computer scientist you are, you may want some proof. I'll indulge you:

    https://goplay.space/#tDBQs1DfE2B

    As mentioned by others and as shown in the sample code, using append can cause a reallocation and copy of the underlying array, which allows the old underlying array to be garbage collected.

提交回复
热议问题