原文链接:

前言

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梦工厂

推荐往期文章: