原文链接:
前言
asongcare
前情概要
在了解内存对齐之前,先来明确几个关于操作系统的概念,更加方面我们对内存对齐的理解。
CPUCPUlinux用户空间内核空间5
内存的知识先介绍个大概,对于本文的理解应该够了,我们接着介绍操作系统几个其他概念。
CPUCPUCPUCPUCPUCPUCPUCPU
ososOperating System
写在最后的一个知识点:
CPUCPUosCPU32CPU432os64CPU32osos
何为内存对齐
以下内容来源于网络总结:
现代计算机中内存空间都是按照字节(byte)进行划分的,所以从理论上讲对于任何类型的变量访问都可以从任意地址开始,但是在实际情况中,在访问特定类型变量的时候经常在特定的内存地址访问,所以这就需要把各种类型数据按照一定的规则在空间上排列,而不是按照顺序一个接一个的排放,这种就称为内存对齐,内存对齐是指首地址对齐,而不是说每个变量大小对齐。
为何要有内存对齐
主要原因可以归结为两点:
CPUCPUCPUCPU
CPU32int324byte0x00000002 - 0x000000054CPU[0x00000000 - 0x00000003]1/2int32int320x00000000
没有内存对齐机制:
内存对齐后:
对齐系数
每个特定平台上的编译器都有自己的默认"对齐系数",常用平台默认对齐系数如下:
- 32位系统对齐系数是4
- 64位系统对齐系数是8
C#pragma pack(n)CGotags命名约定GoGo
Gounsafe.Alignof2^n8
注意:不同硬件平台占用的大小和对齐值都可能是不一样的。
结构体的内存对齐规则
一提到内存对齐,大家都喜欢拿结构体的内存对齐来举例子,这里要提醒大家一下,不要混淆了一个概念,其他类型也都是要内存对齐的,只不过拿结构体来举例子能更好的理解内存对齐,并且结构体中的成员变量对齐有自己的规则,我们需要搞清这个对齐规则。
C语言GoC语言Go
00offset
举个例子
根据上面的对齐规则,我们来分析一个例子,加深理解:
mac648int32[]int32stringbool4881424161User
int32[]int322424884-70932Bstring816user32offset3283248Cbool111user4848D4849D
49
8248498567
成员变量顺序对内存对齐带来的影响
根据上面的规则我们可以看出,成员变量的顺序也会影响内存对齐的结果,我们先来看一个例子:
运行结果:
test1
test2
)
通过以上分析,我们可以看出,结构体中成员变量的顺序会影响结构体的内存布局,所以在日常开发中大家要注意这个问题,可以节省内存空间。
空结构体字段对齐
Go0
demo1bastruct{}struct{}
考虑内存对齐的设计
sync.waitgroupstate1
state112
83232goroutine4
(wg *WaitGroup) state() (statep *uint64, semap *uint32)state1
646432waitGroup3264位648state
8864432semaphore84semaphore864
)
总结
终于接近尾声了,内存对齐一直面试中的高频考点,通过内存对齐可以了解面试者对操作系统知识的了解程度,所以这块知识还是比较重要的,希望这篇文章能帮助大家答疑解惑,更好的忽悠面试官~。
文中有任何问题欢迎留言区探讨~;
欢迎关注公众号:Golang梦工厂
推荐往期文章: