Go语言核心知识
本文最后更新于 2024-05-16,文章内容可能已经过时。
1.切片:
type slice struct {
array unsafe.Pointer
len int
cap int
}
在切片达到容量上限时,继续 append 操作会导致切片扩容。扩容是为切片分配新的内存空间并拷贝原切片中元素的过程。
如果go 1.18+,原来的slice 容量oldcap小于256的时候,新 slice 的容量newcap是oldcap 的2倍;当oldcap容量大于等于 256 的时候,newcap会有个计算公式:newcap += (newcap +3*threshold) / 4 再对 newcap 作了一个内存对齐,这个和内存分配策略相关。进行内存对齐之后,新 slice 的容量是要大于等于按照前半部分生成的newcap。
线程不安全:手动channel.锁
2.哈希表:
数据结构:
hmap,[]bmap,溢出桶.
两次哈希:前八位
线程不安全
3.defer:
最后声明的 defer 语句会被最先执行。 关于修改返回值, defer 语句在函数返回之后执行,但是它可以访问并修改返回值。 这是因为返回值在函数结束时会被当作 defer 语句的参数。
4.gc:
三色,对应了垃圾回收过程中对象的三种状态:
灰色:对象还在标记队列中等待
黑色:对象已被标记,
gcmarkBits
对应位为1
(该对象不会在本次 GC 中被回收)白色:对象未被标记,
gcmarkBits
对应位为0
(该对象将会在本次 GC 中被清理)
根对象在垃圾回收的术语中又叫做根集合,它是垃圾回收器在标记过程时最先检查的对象,包括:
全局变量:程序在编译期就能确定的那些存在于程序整个生命周期的变量。
执行栈:每个 goroutine 都包含自己的执行栈,这些执行栈上指向堆内存的指针。 寄
存器:寄存器的值可能表示一个指针,参与计算的这些指针可能指向某些赋值器分配的堆内存区块。
Go V1.8版本引入了混合写屏障机制(hybrid write barrier),避免了对栈re-scan的过程,极大的减少了STW的时间。结合了两者的优点。
GC开始将栈上的对象全部扫描并标记为黑色。
GC期间,任何在栈上创建的新对象,均为黑色。
被删除的对象标记为灰色。
被添加的对象标记为灰色。
5.gm:
全局的协程队列+线程池维护内核态线程
6.gmp:
更加灵活地进行协程之间的调度。
P(Processor):虚拟处理器,M执行G所需要的资源和上下文,只有将 P 和 M 绑定,才能让 P 的 runq 中的 G 真正运行起来。P 的数量决定了系统内最大可并行的 G 的数量
全局队列+每个p本地队列的方式,简化锁的开销。
work stealing:
干完活的线程与其等着,不如去帮其他线程干活。
hand off:
当前线程M阻塞时,释放P,给其它空闲的M处理.