终于理解了Slice扩容机制
目录
警告
本文最后更新于 2020-05-08,文中内容可能已过时。
写了很久的slice却没有去想过他的扩容机制,近期面试,去了解了一下,这次也算是彻底明白了,之前只是简单的看了看文章
STEP1 预估扩容后容量
先看一个例子
|
|
了解一下预估规则
-
在原容量扩大两倍还要小于扩容后的容量时,预估容量就是扩容后的
-
当大于扩容后的时,如果小于1024时,预估容量是扩容前容量的2倍
-
当大于扩容后的时,如果大于1024时,预估容量是扩容前容量的1.25倍,即以0.25增加
STEP2 需要多大内存
所需内存 = 预估容量 * 元素类型大小
这里以int
举例,int在64位操作上默认是int64,即8个字节,所以元素类型不一样,内存也不一样,内存这里需要了解golang
的内存管理模块,源码在runtime/sizeclasses.go
|
|
通过阅读源码可以知道,在小于16字节时,每次以8个字节增加,当大于16小于2^8时,每次以16字节增加,当大于2^8小于2^9时以32字节增加,依此规律…
申请内存时,选择相近的,且大于等于需要的大小
STEP3 匹配到合适的内存规格
- 在之前的例子中,预估容量为5
- 1个int是8个字节,5 * 8 = 40
- 最合适的内存规格是48,所以48 / 8 = 6
- 所以内存会扩容到
6
个容量
Practice
下面代码输出什么?
|
|
长度是62,这无疑,重点是容量计算,两倍的旧容量小于预估计的容量,所以预估计容量成了62, 62 * 8 = 496,在内存规格中选择到了512,所以512 / 8 = 64,即cap(a) = 64。