Go切片扩容机制

首先,我们创建一个数组

image-20220120221720455

然后我们又声明了一个s1变量,把数组s分片,此时s1是一个切片,切片有三个域,其中一个存的就是数组指针,它就指向了这个数组1号下标,然后长度为2,容量为5。

image-20220120221854638

然后我们再声明一个s2变量,也是把数组s分片,此时就是如下图所示。

image-20220120222103988

如果此时我们修改s的值,如果在s1和s2的范围中,s1和s2的值也会改变,因为s1和s2都指向了这个数组。

而此时如果我们通过s2 = append(s2, 999)来给s2追加一个值,会发生什么? 可见s2已经无法在原来的数组上追加了,此时再追加元素,就会触发扩容机制。

扩容机制:

比如我们有一个容量为2的切片,此时再添加3个元素,我们的容量至少要扩到5,5就是我们的预估容量。

那么我们此时就要判断,如果原来的容量翻倍还是小于这个预估容量,那么我们直接让容量等于预估容量。

否则,看原来切片的容量如果小于1024,那么直接翻倍,如果大于等于1024,每次扩1/4,直到新容量超过所需容量。

image-20220209223741289

第三步就是申请内存,在很多语言中,内存分配不是直接和操作系统交互的,而是和语言自身的内存管理模块交互,而自身的内存管理模块会提前先向操作系统申请一批内存,分成常用的规格管理起来。

当我们申请内存的时候,它会给我们分配足够大且最接近的规格,比如下面的24字节,就会被分配32个字节。

在我们第二步中,我们知道最终的预估容量是5,64位下就需要申请5 * 8 = 40byte字节存放扩容后的底层数组,而实际上申请时会匹配到48字节,48个字节能装48 / 8 = 6个元素(如果是32位操作系统,把前面的8变成4就可以了),这就是我们扩容后的容量了。

image-20220210081435419

此时会创建一个新数组,这个新数组会首先把原数组的内容拿过来,然后在基础上添加元素,再让这个切片指向这个数组。

此时再修改s的内容,不会影响到s2。

image-20220120224510798

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jacob_云飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值