切片扩容是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