切片扩容是go中比较常见的操作
如果扩容后的容量,未超过底层数组的容量。会改变底层数组的数据
如果扩容后的容量,超过底层数组的容量。memove会产生新的切片地址
在 1.18 版本前,切片扩容,在容量小于1024时,以2倍大小扩容。超过1024后,以1.25倍扩容。
在扩容后切片的基础上,会根据长度和容量进行 roundupsize 。
在1.18版本后,切片扩容,在容量小于256时,以2倍大小扩容。超过256后,以(1.25倍+192)扩容。
newcap := old.cap
doublecap := newcap + newcap
if cap > doublecap {
newcap = cap
} else {
const threshold = 256
if old.cap < threshold {
newcap = doublecap
} else {
// Check 0 < newcap to detect overflow
// and prevent an infinite loop.
for 0 < newcap && newcap < cap {
// Transition from growing 2x for small slices
// to growing 1.25x for large slices. This formula
// gives a smooth-ish transition between the two.
newcap += (newcap + 3*threshold) / 4
}
// Set newcap to the requested cap when
// the newcap calculation overflowed.
if newcap <= 0 {
newcap = cap
}
}
}
roundupsize : 通过切片总内存和内存分配表做对比,选中区间范围,再向上取整后除以切片首元素的内存,得到最终扩容。
分配表所在文件 bytes/obj字段, $GOROOT/src/runtime/sizeclasses.go:4