iOS底层探索--内存对齐

147 阅读2分钟

内存对齐:

数据项仅仅能存储在地址是数据项大小的整数倍的内存位置上,不满整数倍的位置往后推移。

内存对齐规则:

1)第一个成员在与结构体变量偏移量为0的位置处。
2)其他成员变量要对齐到某个数字(对其数)的整数倍的地址处。对其数=编译器默认的一个对齐数与该成员大小的较小者。
vs中默认的值是8
Linux中默认的值是4
3)结构体总大小为最大对其数(每一个成员变量都有一个对其数)的整数倍。
4)如果嵌套了结构体对齐到自己的最大对其数是整数倍处,结构体的整体大小就是最大对齐数(含嵌套结构体的对齐数)的整数倍。

获取内存大小的三种方式分别是:

sizeof
class_getInstanceSize
malloc_size

sizeof
1sizeof是一个操作符,不是函数
2、我们一般用sizeof计算内存大小时,传入的主要对象是数据类型,这个在编译器的编译阶段(即编译时)就会确定大小而不是在运行时确定。
3sizeof最终得到的结果是该数据类型占用空间的大小

class_getInstanceSize
,是runtime提供的api,用于获取类的实例对象所占用的内存大小,并返回具体的字节数,其本质就是获取实例对象中成员变量的内存大小

malloc_size
这个函数是获取系统实际分配的内存大小

各中类型所占字节:

结构体所占内存大小计算:

struct MKStruct1 {
    int a;      // 4 (0-3)
    char b;     // 1 [4 1] (4)
    int c;      // 4 [5 4] 5 6 7 (8 9 10 11)
    short d;    // 2 [12 2] (12 13)
    int e;     // 4 [14 8] (16,17,18,19)
    int f;     //  4 [20 4] (20,21,22,23)
}struct1;



// 内部需要的大小为: 24
// 最大属性 : 4
// 结构体整数倍: 24
//

// 15 -> 16

struct MKStruct2 {
    double a;      //8 (0-7)
    int b;      //4 (8 9 10 11)
    char c;     //1 (12)
    short d;    //2 13 (14 15) - 16
}struct2;
// 15 -> 16

struct MKStruct3 {
    
    double a;   //8 (0 7)
    int b;      //4 (8 11)
    char c;     //1 (12)
    short d;    //2  13 (14,15)
    struct MKStruct1 struct3; // 24 (
    struct MKStruct2 struct4; // 16
}struct3; //56 因为结果内字节最大的是 double(8字节) 所以56恰好是8的倍数,所以从输出结果可以看出。

通过sizeof获得结构大小:
 	NSLog(@"\n 结构体1:%lu \n 结构体2:%lu \n 结构体3:%lu",sizeof(struct1),sizeof(struct2),sizeof(struct3));

结果如下:     
       2020-09-09 18:02:13.462060+0800 001-内存对齐原则[10086:3914048] 
 		结构体124 
 		结构体2:16 
 		结构体3:56

总结: