Golang1.17源码分析之slice-001

Golang1.17 学习笔记001

一、slice

核心概念:切片和数组之间、切片和切片之间都是共享内存的。只要切片不发生扩容,那么都是操作的同一个地址

arr := [5]int{1,2,3,4,5}
s1 := arr[2:5]
arr[2] = 9
fmt.Println(s1) // [9,4,5] -- 共享内存s1 = append(s1,6) // 发生扩容,不再共享内存
arr[3] = 10
fmt.Println(s1) // [9,4,5,6]
fmt.Println(arr) // [1,2,9,4,5]

源码包:runtime/slice.go

数据结构:

type slice struct {array unsafe.Pointer // 指向底层数组的指针len   int           // 长度cap   int           // 容量
}

创建:这里创建规则跟 go 的内存管理有关,建议看完内存管理之后再看这里

  • 小于 32kb 的对象从 per-p 缓存空闲列表中创建

  • 大于 32kb 的对象从堆中进行创建

  • 使用 new 创建 slice 无法直接使用 slice[0] 这种来赋值,需要使用 append 添加,此时才会给 slice 分配底层数组

func makeslice(et *_type, len, cap int) unsafe.Pointer {mem, overflow := math.MulUintptr(et.size, uintptr(cap))if overflow || mem > maxAlloc || len < 0 || len > cap {mem, overflow := math.MulUintptr(et.size, uintptr(len))if overflow || mem > maxAlloc || len < 0 {panicmakeslicelen()}panicmakeslicecap()}return mallocgc(mem, et, true)
}// Small objects are allocated from the per-P cache's free lists.
// Large objects (> 32 kB) are allocated straight from the heap.
func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {if size <= maxSmallSize { // maxSmallSize = _MaxSmallSize  = 32768size = uintptr(class_to_size[sizeclass])spc := makeSpanClass(sizeclass, noscan)span = c.alloc[spc]v := nextFreeFast(span)if v == 0 {v, span, shouldhelpgc = c.nextFree(spc)}x = unsafe.Pointer(v)} else {span, isZeroed = c.allocLarge(size, needzero && !noscan, noscan)span.freeindex = 1span.allocCount = 1x = unsafe.Pointer(span.base())}
}

复制:

为什么 copy(小,大) 可以不报错,原因如下

func slicecopy(toPtr unsafe.Pointer, toLen int, fromPtr unsafe.Pointer, fromLen int, width uintptr) int {if fromLen == 0 || toLen == 0 {return 0}n := fromLenif toLen < n {n = toLen}   if size == 1 { // common case worth about 2x to do here// TODO: is this still worth it with new memmove impl?*(*byte)(toPtr) = *(*byte)(fromPtr) // known to be a byte pointer} else {memmove(toPtr, fromPtr, size)}return n
}

扩容:

  • 如果新容量大于 2 倍原容量,那么就扩容至新容量
  • 如果新容量小于 2 倍原容量,且原容量小于 1024,那么新容量扩容至 2 倍原容量
  • 如果新容量小于 2 倍原容量,且原容量大于 1024,那么新容量一直按原容量的 1/4 进行扩容,直到当前容量大于传入的新容量
func growslice(et *_type, old slice, cap int) slice {newcap := old.capdoublecap := newcap + newcapif cap > doublecap {newcap = cap} else {if old.cap < 1024 {newcap = doublecap} else {// Check 0 < newcap to detect overflow// and prevent an infinite loop.for 0 < newcap && newcap < cap {newcap += newcap / 4}// Set newcap to the requested cap when// the newcap calculation overflowed.if newcap <= 0 {newcap = cap}}}memmove(p, old.array, lenmem)return slice{p, old.len, newcap}
}

参考文献:《GO专家编程》之 slice 篇、Golang1.17源码

001-Golang1.17源码分析之slice相关推荐

  1. 每日源码分析 - Lodash(remove.js)

    本系列使用 lodash 4.17.4版本 源码分析不包括引用文件分析 一.源码 import basePullAt from './.internal/basePullAt.js'/*** Remo ...

  2. live555 源码分析:播放启动

    本文分析 live555 中,流媒体播放启动,数据开始通过 RTP/RTCP 传输的过程. 如我们在 live555 源码分析:子会话 SETUP 中看到的,一个流媒体子会话的播放启动,由 Strea ...

  3. live555 源码分析:子会话 SDP 行生成

    如我们在前文 live555 源码分析:ServerMediaSession 中看到的,H264VideoFileServerMediaSubsession 的继承层次体系如下图: 在这个继承层次体系 ...

  4. caffe.proto源码分析

    一什么是protocol buffer 二caffeproto中的几个重要数据类型 三caffeproto源码 分析caffe源码,看首先看caffe.proto,是明智的选择.好吧,我不是创造者,只 ...

  5. 决策树(十)--GBDT及OpenCV源码分析

    一.原理 梯度提升树(GBT,Gradient Boosted Trees,或称为梯度提升决策树)算法是由Friedman于1999年首次完整的提出,该算法可以实现回归.分类和排序.GBT的优点是特征 ...

  6. 决策树(七)--Boost及源码分析

    原文:http://blog.csdn.net/zhaocj/article/details/50536385 一.原理 AdaBoost(Adaptive Boosting,自适应提升)算法是由来自 ...

  7. [源码分析] Facebook如何训练超大模型 --- (3)

    [源码分析] Facebook如何训练超大模型 - (3) 文章目录 [源码分析] Facebook如何训练超大模型 --- (3) 0x00 摘要 0x01 ZeRO-Offload 1.1 设计原 ...

  8. Swin Transformer源码分析

    swin transformer是什么这里就不在说明了,会点进来肯定是知道这个模型是做什么的. 直接看论文有些地方看的一知半解.这里直接从源码分析看下模型的具体实现 论文地址:https://arxi ...

  9. 【ROS-Navigation】Costmap2d代价地图源码分析——ObstacleLayer障碍物层

    在学习ROS-Navigation源码过程中,记录自己的理解,本文为分层代价地图中障碍物层源码的学习笔记,针对obstacle_layer.h和obstacle_layer.cpp源码文件,分析障碍物 ...

最新文章

  1. html页面引入另一个html页面
  2. 在C#中操作XM II
  3. Kafka集群在马蜂窝大数据平台的优化与应用扩展
  4. 关于设置不同linux主机之间ssh免密登录简易方法
  5. JSP企业人事管理系统
  6. Oracle 索引原理和种类
  7. iOS开发音频格式转换
  8. 特殊符号大全(建议收藏_复制着用_数学符号最下面)
  9. bzoj1190梦幻岛宝珠
  10. codeforces 711 C. Coloring Trees (dp)
  11. 为啥说外包公司不能去?
  12. VSTO开发入门教程(bili网站搜罗VSTO免费视频资源)
  13. 中国独角兽企业前景预测及投资规划建议报告2022-2028年版
  14. 网易传媒计算机视觉算法实习生面试总结
  15. 多模态情感识别(MER)数据集整理
  16. 1-Java面试题-基础篇
  17. BPO业务分析行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  18. 【怎样制作ppt课件】Focusky教程 | 卸载Focusky
  19. 我刚创建了一个开源项目OXmlEd,欢迎大家拍砖
  20. 2021年最新vue面试题及答案

热门文章

  1. 梦想CAD提示过期问题的处理
  2. 使用ListBox控件,选中ListBoxItem中的TextBox后,如何改变SelectedItem
  3. All-New Kindle App: 亚马逊的产品之道
  4. Flowable工作流引擎的使用3(task审批节点的接受与使用)
  5. 关于 win10 创建WiFi热点 问题(无法启动承载网络 , 我们无法设置移动热点,因为你的电脑未建立以太网,wifi或手机网络数据连接 )...
  6. C语言程序设计之小超市管理系统(只有存储货物)
  7. 34岁央企女工程师,月入两万五,一家芯片公司给出60万年薪,要不要去?
  8. Python实现AO*算法进行与或图搜索
  9. Centos 7 验证码不显示问题
  10. 鼠标闲置一段时间后自动隐藏