Go语言 Slice 结构的底层实现
append 性能损耗
未指定长度或者长度不足时,双倍扩容(cap < 1024); 1.25倍扩容(cap > 1024)。把元内存空间的数据拷贝过来,然后在新的内存空间继续append数据
在 Go 1.18 以后,扩容使用threshold为临界点(源码中设置为256)
当slice容量 < 256时, 每次扩容为原来的两倍。当slice容量 > 256时, 每次增加(oldcap + 3*threshold) 3/4
母子切片共享内存问题
1 | slicem := make([]int, 3, 5) // len = 3, cap = 5 分配了5个空间,置入了3个数据 |
最开始时,子切片和母切片共享母切片的内存空间,对子切片的修改会反映到母切片上,对子切片的 append 操作,会将数据添加到母切片预留的内存空间内。
如持续进行 append 操作,直到将母切片预留的内存空间完全消耗完毕后,二者就会发生内存分离,从此再无关系
切片导致内存泄漏
1 | func Leak() []int { |
func 返回子切片,只要这个子切片没有被 GC 回收,子切片持有的母切片的内存空间就得不到释放,导致泄漏
函数参数需要用切片指针么
如果函数内部需要对切片的 len 和 cap 进行修改,且修改要反映在函数外部,那么需要传入切片的指针
一边遍历一边修改切片
1 | arr := []int{1,2,3} |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Bishop!
评论
GitalkValine