内存对齐原则

作者: 小满豆 | 来源:发表于2019-12-18 15:19 被阅读0次

导引

首先看一个例子:

例子 例子NSLog NSLog结果

从图中看出,打印结果不同,这是为什么呢?

基础知识(arm64)

char 1字节;    short   2字节 ; int   4字节;  double  8字节

对齐原则

1:数据成员对⻬规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int为4字节,则要从4的整数倍地址开始存储。

2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)

3:收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补⻬。

这是内存对齐原则,接下来我们要对其进行一一验证,探究出为什么打印结果不同。

验证

MyStructOne(初始 size = 0)

1. a占用1字节,起始位置为0,即offset = 0,size = 1。

2. b占用2字节,根据原则1,b的起始位置要为2的倍数,所以b起始位置为2(size + 1),即offset = 2, size = 1 + 1 + 2 = 4。

3. c占用8字节,根据原则1,c的起始位置要为8的倍数,所以c起始位置为8(size + 4),即offset = 8,size = 4 + 4 + 8 = 16。(同b)

4. d占用4字节,根据原则1,d的起始位置要为4的倍数,所以d起始位置为16(size 占用0-15位),即offset = 16,size = 16 + 4 = 20。

5. 最终size不满足原则3,那么size = 24(为8*3)。

最终得出结果: sizeof(MyStructOne) = 24

MyStructTwo(初始 size = 0)

1. c占用8字节,起始位置为0,即offset = 0,size = 8。

2. a占用1字节,根据原则1,c的起始位置要为1的倍数,所以c起始位置为8(size),即offset = 8,size = 8 + 1 = 9。

3. b占用2字节,根据原则1,b的起始位置要为2的倍数,所以b起始位置为10(size + 1),即offset = 10, size = 9 + 1 + 2 = 12。

4. d占用4字节,根据原则1,d的起始位置要为4的倍数,所以d起始位置为12(size占用0-11位),即offset = 12,size = 12 + 4 = 16。

5. size满足原则3,size = 16。

最终得出结果:sizeof(MyStructTwo) = 16


为了验证原则2,我在MyStructOne里添加MyStructThree(已算出大小为24)如下图:

结构体嵌套结构体 NSLog结果

从图中可以看出MyStructOne为48,MyStructThree作为MyStructOne里的元素,MyStructThree内最大的为8,所以MyStructThree的起始位置应该为8的倍数,MyStructOne前边的元素大小为24,MyStructThree起始位置为24,最终MyStructOne为48。

总结

1. 编译器在进行编译时,对每个数据的在内存的排放都是有一定规则的。

2. 数据声明顺序的不同会导致内存结构的不同。这样我们可以通过按照数据类型来调整结构体内部的数据的先后顺序来尽量减少内存的消耗。

补充

内存对齐的好处(原因)

1.平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

2.性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

相关文章

  • 内存对齐原则

    导引 首先看一个例子: 从图中看出,打印结果不同,这是为什么呢? 基础知识(arm64) char 1字节; s...

  • iOS底层探索-calloc

    一、calloc底层探索 1.1、内存对齐原则 a:数据成员对齐规则:结构(struct)(或联合(union))...

  • iOS 内存对齐

    一、结构体内存对齐 1.1 结构体内存对齐三大原则 数据成员对⻬规则结构体(struct)或联合体(union)的...

  • 苹果内存对齐原则

    alloc主要创建流程 这里最重要的方法就是这三个: cls->instanceSize calloc obj->...

  • iOS内存对齐原则

    内存对齐原则: 1、数据成员对⻬规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在o...

  • 内存对齐的原则

    1、数据成员对齐规则:结构(struct)或union的数据成员,第一个数据的成员,放在offset为0 的地方,...

  • iOS结构体内存对齐原则初探

    为什么OC对象在开辟内存的时候会有内存对齐原则,在对象申请内存的时候是16字节对齐的,在真正开辟所需要的内存时时8...

  • 2.iOS底层学习之内存对齐

    学习了内存对齐之后的疑问?? 1.为啥要内存对齐?2.内存对齐的规则?3.内存对齐实例分析。 内存对齐的目的 上网...

  • 结构体内存对齐

    不同数据类型占用字节图 内存对齐的原则 1、数据成员对齐规则: 结构(struct)(或联合(union)的)数据...

  • 内存对齐

    本次主要讨论三个问题: 什么是内存对齐 内存对齐的好处 如何对齐 内存对齐 内存对齐是一种提高内存访问速度的策略。...

网友评论

    本文标题:内存对齐原则

    本文链接:https://www.haomeiwen.com/subject/gtyxnctx.html