Go语言切片扩容后无引用的原底层数组会被内存回收吗?
切片扩容后原底层数组的内存回收问题
问题描述
当切片创建新底层数组且原数组不再被切片或其他变量引用时,原底层数组会发生什么?
假设我们创建一个长度为3、容量为4的切片,随后尝试追加元素使其超出容量:
slice := make([]int, 3, 4) slice = append(slice, 6, 7) // 追加7时超出容量 fmt.Println(slice)
在上述程序中,原数组不再被切片或其他变量引用,它的内存会被释放还是会一直占用到程序结束?
回答
原底层数组会被Go的**垃圾回收器(GC)**自动回收,不会一直占用内存到程序结束。
具体逻辑如下:
- 调用
append且元素数量超出切片容量时,Go运行时会分配一块新内存作为新的底层数组(通常容量是原容量的2倍,这里原容量4,新容量会变为8),并把原数组的元素拷贝到新数组中,再追加新元素。 - 赋值语句
slice = append(...)会让原切片变量指向新的底层数组,此时原底层数组不再被任何可达的变量或切片引用。 - Go的追踪式垃圾回收器会定期扫描内存对象,一旦发现某个对象(这里就是原底层数组)没有任何可达引用,就会在合适的回收周期里释放它占用的内存。
需要注意:
- GC的回收时机由Go运行时调度,不是在原数组失去引用后立即执行,但可以确定它不会一直占用内存。
- 如果原底层数组还被其他切片或变量持有引用,那它就不会被回收,直到所有指向它的引用都消失。
内容的提问来源于stack exchange,提问作者Pranaav S
相关产品推荐
相关产品推荐

