美文网首页
002-OC对象原理探究 - 结构体内存对齐

002-OC对象原理探究 - 结构体内存对齐

作者: Mr_wick | 来源:发表于2021-06-16 15:40 被阅读0次

引言

上一篇文章,探究 alloc的过程中,提到内存对齐。下面我们通过对OC对象QLPerson探究来展开内存对齐的探究。

OC对象本质

我们探究oc对象底层的本质,通过如下方式,讲.m文件转为.cpp文件。参考我的这篇文章
QLPerson.h 代码如下:

image.png
QLPerson.m 如下:
image.png
我通过xcrun来转成cpp文件
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc QLPerson.m -o QLPerson.cpp

QLPerson.cpp拖入xcode,compile sources去掉QLPerson.cpp,使其不参与编译。在QLPerson.cpp中搜索QLPerson_找到底层实现为结构体QLPerson_IMPL

image.png
其中结构体NSObject_IMPL
struct NSObject_IMPL {
    Class isa;
};

由此可得出OC对象的本质是结构体,引出我今天将要探究的结构体内存对齐

结构体内存对齐探究:普通成员变量

定义结构体代码如下:

struct QLStruct1 {
    double  a;  // 8   
    char    b;  // 1   
    int     c;  // 4   
    short   d;  // 2   
} struct1; 
其中每个成员变量后面的注释为类型所占字节大小

那么struct1的内存到底占多少呢?我们这里用sizeof()来计算结果:

NSLog(@"%lu",sizeof(struct1));
打印结果如下: image.png

这24字节是怎么得到的?
首先,我们要了解,结构体对齐有如下原则:

1、数据成员对齐规则:结构(struct)或union的数据成员,第一个数据的成员,放在offset为0 的地方,以后每个数据成员存储的起始位置,要从该成员大小成员的子成员大小(只要该成员有子成员,数组、结构体等)的整数倍开始。
2、结构体作为成员:如果一个结构里,有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。
3、结构体的总大小,也就是sizeOf的结果,必须是其内部成员的整数倍,不足的要补齐
根据内存对齐原则,得到下图是struct1的成员变量的分布情况(excel画的) image.png

代码如下:

struct QLStruct1 {
    double  a;  // 8   0 1 2 3 4 5 6 7
    char    b;  // 1   8
    int     c;  // 4   (9,10,11) 12 13 14 15
    short   d;  // 2   16 17
} struct1;      // 总计:成员变量总和为17,收尾--最大成员变量double(8)的倍数 --> 24
小括号为跳过

9,10,11为什么会空出来,因为struct1的最大成员变量为double,也就是最大成员变量的大小为8字节,根据原则1,可知该结构体按8字节对齐。char b排到8后,int c本应该从9开始排,但是9不能被8整除,因此往后移到12开始分配4字节int c
short d排布结束后,到了17,根据原则3struct1按照8字节内存对齐,不足的需要补齐,因此,最终sizeof(struct1)得到的是24而不是17

结构体内存对齐探究:结构体作为成员变量

struct QLStruct3 {
    double  a;              // 8    0-7
    int     b;              // 4    8 9 10 11
    char    c;              // 1    12
    short   d;              // 2    (13)14 15
    int     e;              // 4    16 17 18 19
    struct  QLStruct1 stru; // 17   (20,21,22,23)24 25 26 27 ... 40
} struct3;                  // 总计:成员变量总和为40,收尾--最大成员变量double(8)的倍数 --> 48
小括号为跳过

根据探究普通成员变量的方式,根据原则2得到sizeof(struct3)的大小为48

总结

结构体内存对齐,要熟记以上3个原则,则面对复杂的结构体,也能得心应手的处理了。

相关文章

  • 002-OC对象原理探究 - 结构体内存对齐

    引言 上一篇文章,探究 alloc的过程中,提到内存对齐。下面我们通过对OC对象QLPerson探究来展开内存对齐...

  • OC底层原理 05: 内存对齐原理

    主动已经是我对热爱东西表达的极限了 通过对结构体内存是如何对齐的?打开内存对齐原理的大门。 在探究内存对齐之前,先...

  • iOS原理探索02-- 内存对齐

    结构体内存对齐 我们首先定义两个结构体,分别计算他们的内存大小,并讨论内存对齐原理 从两个结构体来看两者没啥大的区...

  • iOS对象原理探究:内存对齐

    在开始之前,我们先了解下接下来会用到的 lldb 调试指令: 接下来,我们还是先举个栗子?。 Person 栗子?...

  • 结构体

    1.结构体 2.结构体的内存对齐模式 编译器在编译一个结构的时候采用内存对齐模式,结构体总是以最大的成员最为对齐单...

  • iOS-内存对齐

    先上个图,待会计算内存时会用到。 hxdm,已知iOS对象的本质是结构体,所以探索内存对齐当然是从结构体开始啦。来...

  • ndk-基础知识

    数组和指针,数组指针,指针数组 结构体 内存对齐 内存对齐 结构体大小 S5DUD10BN083MHEJEX7TP...

  • iOS--OC底层原理文章汇总

    OC底层原理01—alloc + init + new原理OC底层原理02—内存对齐OC底层原理03— isa探究...

  • Synchronized 锁升级过程

    对象结构 Java 对象存储在堆中,那么一个java对象在内存中的结构哪些信息呢?包含对象头,对象体和对齐字节,以...

  • 内存对齐详解

    1、什么是内存对齐假设我们声明两个变量: 2、结构体内存对齐规则 结构体所占用的内存与其成员在结构体中的声明顺序有...

网友评论

      本文标题:002-OC对象原理探究 - 结构体内存对齐

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