切片是如何扩容的?有哪些规则?
切片是如何扩容的?有哪些规则?
提示
题眼: 1.18 版本前后的变化
- Go 1.17 及以前:切片扩容时会结合内存分配策略做容量调整。通常可以概括为:
- 如果新切片期望容量大于旧容量的 2 倍,就直接扩到期望容量。
- 如果旧容量小于 1024,通常按 2 倍扩容。
- 如果旧容量大于等于 1024,则通常按 1.25 倍逐步增长,直到满足期望容量。
- Go 1.18 之后:阈值从 1024 调整成了 256,增长策略也随之修改:
- 如果期望容量大于旧容量的 2 倍,直接扩到期望容量。
- 如果旧容量小于 256,通常按 2 倍扩容。
- 如果旧容量大于等于 256,则进入平滑增长逻辑,而不是简单固定的 1.25 倍。
重要
参考答案:
切片底层是数组,所以扩容的核心逻辑并不复杂:当容量不够时,先申请一个更大的新数组,再把原数组内容拷贝过去,最后让切片指向新的底层数组。
比较关键的是“新数组到底申请多大”。在 Go 1.18 之前,整体规律可以理解为:小切片更倾向于翻倍增长,大切片则更倾向于按较小比例平滑增长。1.18 之后,这个阈值从 1024 调整成了 256,增长策略也更细了。
面试里把大方向答清楚就够了:小容量增长更激进,大容量增长更平滑,最终还会结合内存分配器做对齐和调整。
相关信息
引申: 为什么要改成 256?你还了解哪些 Go 版本的更新优化?
