Go GC是否处理数组的未着色部分
假设我们这样创建了一个切片:Go GC是否处理数组的未着色部分,go,garbage-collection,Go,Garbage Collection,假设我们这样创建了一个切片: arr := make([]byte, 0, 10) arr = append(arr, []byte{1, 1, 1}...) arr := make([]byte, 0, 10) arr = append(arr, []byte{1, 1, 1}...) 然后我们要释放7个尾部字节: arr = arr[:len(arr)] arr = arr[:len(arr)] 我们让鱼片的尾巴无法触及。GC会在下一次扫描迭代中简单地声明这个内存空闲吗?或者底层数组
arr := make([]byte, 0, 10)
arr = append(arr, []byte{1, 1, 1}...)
arr := make([]byte, 0, 10)
arr = append(arr, []byte{1, 1, 1}...)
然后我们要释放7个尾部字节:
arr = arr[:len(arr)]
arr = arr[:len(arr)]
我们让鱼片的尾巴无法触及。GC会在下一次扫描迭代中简单地声明这个内存空闲吗?或者底层数组会发生其他情况(例如,copy()
,内存根本不会被释放)
假设我们这样创建了一个切片:
arr := make([]byte, 0, 10)
arr = append(arr, []byte{1, 1, 1}...)
arr := make([]byte, 0, 10)
arr = append(arr, []byte{1, 1, 1}...)
然后我们要释放7个尾部字节:
arr = arr[:len(arr)]
arr = arr[:len(arr)]
你不能;Go GC不执行部分释放。这10个字节将一直保持分配状态,直到没有对这10个字节的任何部分的引用为止 例如,要释放尾部字节
package main
import "fmt"
func main() {
arr := make([]byte, 0, 10)
arr = append(arr, []byte{1, 1, 1}...)
// free tail bytes:
fmt.Println(len(arr), cap(arr), &arr[0], arr)
arr = append(make([]byte, 0, len(arr)), arr...)
fmt.Println(len(arr), cap(arr), &arr[0], arr)
}
游乐场:
输出:
3 10 0x414020 [1 1 1]
3 3 0x414050 [1 1 1]
这并非遥不可及:@JimB我猜,在如此短的程序中,gc扫描不会发生。不,这是切片规范的一部分,
arr[:len(arr)]
不会改变容量。GC将在备份数组不再使用时收集它。表达式arr[:len(arr)]
不会使尾部无法访问。例如,您可以写入tail:=arr[len(arr):cap(arr)]
以获取尾部。@RobLucci否,因为根据规范,您可以作为连续内存块访问片的容量。您的示例中的内存不是无法访问的。