前言
这篇文章中OC底层——alloc分析我们提到过一个align16
16字节对齐算法,下面我们就来探索下内存对齐原则。
内存对⻬的原则
1、数据成员对⻬规则:结构(
struct
)(或联合(union))的数据成员,第
⼀个数据成员放在
offset
为0的地⽅,以后每个数据成员存储的起始位置要
从该成员⼤⼩或者成员的⼦成员⼤⼩(只要该成员有⼦成员,⽐如说是数组,
结构体等)的整数倍开始(⽐如int为4字节,则要从4的整数倍地址开始存
储。
min(当前开始的位置m n) m = 9 n = 4
9 10 11 12
2、结构体作为成员:如果⼀个结构⾥有某些结构体成员,则结构体成员要从
其内部最⼤元素⼤⼩的整数倍地址开始存储.(
struct
a⾥存有
struct
b,b
⾥有
char,int ,double
等元素,那b应该从8的整数倍开始存储.)
3、收尾⼯作:结构体的总⼤⼩,也就是
sizeof()
的结果,.必须是其内部最⼤
成员的整数倍.不⾜的要补⻬。
下图为各种数据类型所占的字节大小
结构体内存对齐
下面用实例来解释内存对齐原理:
#import <objc/runtime.h>
// 结构体内存对齐
struct LGStruct1 {
double a; // 8 [0 7]
char b; // 1 [8]
int c; // 4 (9 10 11 [12 13 14 15]
short d; // 2 [16 17] 24
}struct1;
struct LGStruct2 {
double a; // 8 [0 7]
int b; // 4 [8 9 10 11]
char c; // 1 [12]
short d; // 2 (13 [14 15] 16
}struct2;
struct LGStruct3 {
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 20]
struct LGStruct1 str; //24 44-> 48
}struct3;
NSLog(@"%lu-%lu-%lu",sizeof(struct1),sizeof(struct2),sizeof(struct3));
结果:
24-16-48
通过打印结果,我们发现LGStruct1和LGStruct2结构体中变量的数量和类型都是一样的,只是顺序不同,但是所占用的内存空间却完全不同,这就是因为内存对齐原理造成的。
再看LGStruct3,结构体嵌套结构体:LGStruct3结构⾥有某些结构体成员,则结构体成员要从
其内部最⼤元素⼤⼩的整数倍地址开始存储.(struct3中最大变量为str, 其最大成员内存字节数为8,根据内存对齐原则,所以struct3实际的内存大小必须是8的整数倍,LGStruct1的内存大小是24,所以20 + 24 == 44 结构体8字节对齐原则
LGStruct3 内存大小为48
)
获取内存大小的3种方式
LGPerson *person = [LGPerson alloc];
person.name = @"LG";
person.nickName = @"lg";
person.age = 21;
person.height = 180;
NSLog(@"%@\n - sizeof打印:%lu\n - class_getInstanceSize打印:%lu\n - malloc_size打印:%lu",person,sizeof(person),class_getInstanceSize([LGPerson class]),malloc_size((__bridge const void *)(person)));
输出结果:
<LGPerson: 0x600002fbc180>
- sizeof打印:8
- class_getInstanceSize打印:48
- malloc_size打印:48
sizeof()
- 是一个判断数据类型或者表达式长度的运算符,而不是一个函数;
- 其作用就是返回一个对象或者类型所占的内存字节数;
- 编译器对 sizeof() 的处理都是在
编译阶段
进行。
class_getInstanceSize()
-
该方法在OC底层——alloc分析中分析
_class_createInstanceFromZone源码实现
中,已经进行过简单的了解。 - 其本质是获取创建的对象至少所需的内存大小,8字节对齐。
malloc_size()
- 堆空间实际分配给对象的内存大小,并且按照16字节对齐,我们可以看到实际分配的内存大小和实际所需的内存大小并不相等。后面有时间会再出一篇详细malloc源码分析的文章,具体分析一下malloc流程。
系统的自我(内存)优化
待...