Eggo-Go语言底层学习

本文深入探讨Go语言的底层机制,包括字符的utf8编码、字符串结构、切片的扩容规则、内存对齐原理以及函数调用栈、协程的工作方式等,揭示Go语言高效运行的秘密。
摘要由CSDN通过智能技术生成

字符咋存?utf8咋编码?string啥结构?

字符

8个比特组成一个字节。
存字符就是存编号。(字符集)

utf8 go语言默认编码

存汉字怎么破 - 定长编码 - 变长编码
在这里插入图片描述

string

s = "test"
s[2] 可以打印,但不能被修改。
要修改的话,可以重新赋值字符串。或者转为slice

在这里插入图片描述
字符串变量可以共享底层内容。

Slice

扩容规则。

1. o'l'd

newCap个元素需多大内存

这里和语言的 内存管理模块 决定。匹配到合适的内存规格。
例如这里 newCap = 5,需要 5*8 = 40byte。
os 给内存会有 8/16/32/48/64/80/96 。。。 这里实际匹配到 48byte。能装6个。
在这里插入图片描述

内存对齐

在这里插入图片描述

  1. cpu 要想从 内存 读取数据,要通过地址总线。
  2. 如果地址总线只有8根,那 256byte 就是最大的寻址空间。
  3. 每次操作一字节太慢,要想一次操作 4字节就需要 32位数据总线,8字节就需要 64位数据总线.(每次操作的字节数,就是机器字长

内存示意

在这里插入图片描述
内存一般分为这种8块,每次取 相同行列的数据,组合起来就是8byte。(有些cpu支持访问任意地址,那是多做了处理。你要取1-8,它会拿0-7, 8-15,拼接起来两次结果。)

  1. 为保证程序高效运行,编译器会把各种类型的数据安排到合适的地址,并占用合适的长度。
  2. 每种类型的对齐值就是它的对齐边界。
    要求:存储地址 与 占用的字节数 都要是它对齐边界的倍数。(下图int32要从4开始,不能从2开始)
    在这里插入图片描述

怎么确定每种类型的对齐边界呢(与平台有关)

32 位机器字长/最大对齐边界:4
64 位机器字长/最大对齐边界:8
减少浪费,提高性能
在这里插入图片描述

结构体的对齐边界

确定各成员对齐值,取其中最大的。
要求,每个成员存储地址开头对最大值取余=0,另外 限制类型大小等于其对齐边界的整数倍

只有每个结构体的大小都是对齐值的整数倍,才能保证数组里每一个都是内存对齐的。

在这里插入图片描述

函数调用栈

call、ret指令 栈针布局

定义的函数会被编译为一堆堆机器指令,写入可执行文件。
执行时,可执行文件被加载到内存。机器指令会对应到虚拟地址空间中(代码段)。
一个函数调用另一个函数,编译器会生成一条call指令(将下一条指令的地址入栈,跳转到被调用函数入口处执行,最后有ret指令跳回)。
函数执行时需要有足够的内存空间,存放局部变量、参数等(存放在虚拟空间的栈)

被调用者是通过 栈指针 加上 相应的偏移 来定位到每个参数和返回值的。
在这里插入图片描述
函数通过call指令跳转,而每个函数开始时会分配栈帧,结束前又会释放自己的栈帧。ret指令又会把栈恢复到call之前的样子(之前要给返回值赋值,再执行defer函数)

返回值

一般认为返回值通过寄存器传递,但Go

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值