为什么要内存对齐?目的是加快内存读取速度,用空间换时间方式获得内存读取性能的提高。
本文探讨3个问题:
1.内存对齐原则和计算。
2.结构体内存占用的计算。
3.获取内存大小的方法。
内存对齐原则和计算
先介绍内存对齐3条原则:
、
、
数据成员存储位置整除对⻬
结构(struct)(或联合(union))的数据成员,第⼀个数据成员放在offset为0的地⽅,以后每个数据成员存储的起始位置要从该成员⼤⼩或者成员的⼦成员⼤⼩的整数倍开始。
计算公式: m为当前开始位置 n为数据成员大小
如果满足m整除n(m%n==0),n就可以从m开始存储
反之继续循环执行m+1换位检查,直到m能整除n就确定当前成员的存储位置。
结构体作为成员内部最大元素大小整数倍地址开始存储
如果⼀个结构⾥有某些结构体成员,则结构体成员要从
其内部最⼤元素⼤⼩的整数倍地址开始存储.
(例如:struct a⾥存有struct b,b⾥有char,int ,double等元素,那b应该从double长度:8的整数倍开始存储.)
结构体sizeOf结果为内部最大成员整数倍(补齐原则)
结构体的总⼤⼩,也就是sizeof的结果,.必须是其内部最⼤
成员的整数倍.不⾜的要补⻬。
以下是常用对象大小参考数据
image.png
结构体内存大小计算和对齐
现象1:两个内部成员相同的结构体排序不一样,占用内存大小不一样。
struct Struct1 {
double a; // size:8 Location:[0,7] startAt 0
char b; // size:1 Location[8] 8%1==0
int c; // size:4 Location:[12 ,15] 9%4!=0 从位置12开始满足12%4==0
short d; // size:2 Location[16,17] 16%2==0
}struct1;
// 内部需要的大小为: 17
// 最大属性 : 8
// 结构体整数倍: 24
//补齐[18~23]需要补齐
struct Struct2 {
double a; //size:8 Location:[0,7] startAt 0
int b; //size:4 Location:[8,11] 8%4==0
char c; //size:1 Location:[12] 12%1==0
short d; //size:2 Location:[14,15] 13%2!=0 14%2==0
}struct2;
// 内部需要的大小为: 15
// 最大属性 : 8
// 结构体整数倍:16
//打印结构体验证计算结果
NSLog(@"%lu-%lu",sizeof(struct1),sizeof(struct2));
image.png
由此现象可以联想到通过把对内存进行优化,减少内存占用量。
2.关于结构体中嵌套结构体作为成员内存计算(待续更新)
获取内存大小的操作方式
获取内存大小的三种方式分别是
sizeOf
class_getInstanceSize
malloc_size
sizeof
最终得到的结果是该数据类型占用空间的大小
class_getInstanceSize
获取类的实例对象所占用的内存大小(实例对象中成员变量的内存大小)
malloc_size
获取系统实际分配的内存大小