众所周知对象最终是以结构体的形式存在,所以通过对结构体的大小的探索来延伸到对象.
struct HRStruct {
int c; //4
double a; //8
char b; //1
char d; //1
}HRStruct;
NSLog(@"HRStruct结构体大小: %lu",sizeof(HRStruct));
以下是输出结果:
为什么会这样呢,带着问题我们继续。
struct HRStruct {
double a; //8
int c; //4
char b; //1
char d; //1
}HRStruct;
仔细观察这个结构体中的变量是相同的,不同的只是顺序.
以下是输出结果:
得出一个结论:根据顺序不同也会造成所占内存大小不同,可是为什么会这样呢?我们继续。
struct HRStruct {
double a; //8
int c; //4
char b; //1
char d; //1
}HRStruct;
struct HRStruct2 {
double a; //8
int c; //4
char b; //1
struct HRStruct str; // 16
}HRStruct2;
以下是输出结果:
内存的计算并不是简单的加法,而是做了一定的调整.
内存的计算是按照以下规则:
各种类型大小,方便计算时查看
struct HRStruct {
int c; //4
double a; //8
char b; //1
char d; //1
}HRStruct;
struct HRStruct {
double a; //8
int c; //4
char b; //1
char d; //1
}HRStruct;
struct HRStruct {
double a; //8
int c; //4
char b; //1
char d; //1
}HRStruct;
struct HRStruct2 {
double a; //8
int c; //4
char b; //1
struct HRStruct str; // 16
}HRStruct2;
通过例1、例2的对比,我们得出一个结论:根据顺序不同也会造成所占内存大小不同。所以通过调整的成员顺序可以优化内存大小、优化内存的布局
,从而提高内存的读取效率
.
结构体中数据成员
是根据内存从小到大的
顺序定义的,根据内存对齐规则来计算结构体内存大小,需要增加有较大的内存padding即内存占位符,才能满足内存对齐规则,比较浪费内存
结构体中数据成员
是根据内存从大到小的
顺序定义的,根据内存对齐规则来计算结构体内存大小,我们只需要补齐少量内存padding
即可满足堆存对齐规则,这种方式就是苹果中采用的
,利用空间换时间,将类中的属性进行重排,来达到优化内存的目的
我们能想到这个点,苹果的开发工程师一定也想到了这个点。
@interface HRTest : NSObject
@property(nonatomic, copy)NSString *name;
@property(nonatomic, copy)NSString *hobby;
@property(nonatomic, assign)double height;
@property(nonatomic, assign)char a;
@property(nonatomic, assign)char ab;
@end
HRTest * t = [HRTest alloc];
t.name = @"Henry";
t.hobby = @"woman";
t.height = 180.0;
t.a = 'a';
t.ab = 'A';
打印结果:
isa
指针直接打印是乱码,但是仔细看还是有一点线索的。
char
类型的变量,这里就是apple对对象进行了属性重排,也就是内存对齐
,验证了之前我们的猜测。结构体是不进行属性重排的,只有对象才会进行属性重排
apple对
double
,float
进行了优化并不是直接存储。
验证一下:
apple通过内存对齐
将对象的内存进行了极致的压榨
,这一点提现在很多地方,真的值得我们学习。