计算机中内存空间是按照 byte 划分的,计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数的倍数,这就是所谓的内存对齐。
OC类本质上是一个结构体。以结构体为例
struct Person {
double a; // 8
char b; // 1
int c; // 4
short d; // 2
}person;
struct Student {
double a; //8
int b; //4
char c; //1
short d; //2
}student;
NSLog(@"======person=%lu----studnt%lu",sizeof(person),sizeof(student));
输出
======person=24----student=16
可以发现改变了结构体变量的排列属性,所占用的内存大小也不一样
内存对齐原则
- 数据成员对⻬规则:
结构(struct)(或联合(union))的数据成员,第⼀个数据成员放在offset为0的地⽅,以后每个数据成员存储的起始位置要从该成员⼤⼩或者成员的⼦成员⼤⼩(只要该成员有⼦成员,⽐如说是数组,结构体等)的整数倍开始(⽐如int为4字节,则要从4的整数倍地址开始存 储。 min(当前开始的位置m n) m = 9 n = 4 , 9 10 11 12 - 结构体作为成员:
如果⼀个结构⾥有某些结构体成员,则结构体成员要从其内部最⼤元素⼤⼩的整数倍地址开始存储.(struct a⾥存有struct b,b⾥有char,int ,double等元素,那b应该从8的整数倍开始存储.) - 结构体的总⼤⼩,也就是sizeof的结果,.必须是其内部最⼤成员的整数倍.不⾜的要补⻬。
结构体
struct Person {
double a; // 8 (0-7)
char b; // 1 (8 ) 第8位是1的倍数
int c; // 4 从第9、10、11位都不是4的倍数,所以从第12位开始,(12-15)
short d; // 2 (16-17)16位是2的倍数
}person;
()内是实际占用用的位
指针变量
如果结构体中的变量是指针变量又是怎样?
将Student中的char c改为指针变量char *c
struct Student {
double a; //8 (0-7)
int b; //4 (8 9 10 11)
char *c; //8 12 13 14 15 (16-23)
short d; //2 (24-25)
}student;
打印
----student=32
指针c占用8个字节,存储的是一段地址空间,而不是一个简单的字符。指针c开始从第16位开始存储地址,实际要占用了26位,需要满足原则三最大元素8的倍数,所以占用32位。
结构体嵌套结构体
根据原则二,如果结构体a中嵌套结构体b,则取结构体b中的最大元素的倍数的位置开始存储。
student 嵌套Person,Person在student中第一个
struct Person {
double a; // 8 (0-7)
char b; // 1 [8 1] (8)
int c; // 4 [9 4] 9 10 11 (12 13 14 15)
short d; // 2 [16 2] (16 17)
}person;
struct Student {
//占用字节大小 实际占用的位
double a; //8, (0-7)
int b; //4 , (8 9 10 11)
char c; //1 , (12)
struct Person p; //24, 13 14 15 ( 16- 39)
short d; //2, ( 40 41)
}student1;
打印
======person=24----student=48
person占24个字节,内部最大变量是double类型,占8位,需要从8的倍数开始
结构体指针
如果是Person结构体指针
struct Student {
//占用字节带下 实际占用的位
double a; //8, (0-7)
int b; //4 , (8 9 10 11)
char c; //1 , (12)
struct Person *p; //8, 13 14 15 ( 16- 23)
short d; //2, ( 24 25)
}student1;
打印
student=32
内存优化
结构体是变量的顺序会影响结构体的内存大小。在oc类中对内存进行了优化
@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) long height;
@property (nonatomic) char c1;
@property (nonatomic) char c2;
@end
Person *person = [Person alloc];
person.name = @"嘿嘿";
person.nickName = @"哈哈";
person.age = 18;
person.c1 = 'a';
person.c2 = 'b';
NSLog(@"====%@",person);
断点调式
发现oc对变量进行了内存优化age,c1,c2 被分配在同一个内存块中。