了解一下lldb调试指令
po 打印信息
p 打印详细的信息
bt 打出堆
register read 读取寄存器
x 读取内存段
x/4gx 读取4段内存段
接下来引入一个列子,创建一个LNDPersonal类
@interface LNDPersonal : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, assign) int age1;
@property (nonatomic, assign) int age2;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) int height;
@end
lldb打印调试,如图
lldb打印分析.png
打印日志结果可以分析出几点:
-
nickName、age1、age2属性不赋予值,内存情况会出现0x0000000000000000; -
age、height属性会出现在同一个8字节里; - 属性在内存中排列乱了;
总结:类本身其实就是一个结构体,默认有一个isa属性占用8字节,苹果对对象的申请内存空间默认16字节整数倍算,但实际开辟是以8字节整数倍算。为了能够较快速访问、避免访问不出错,则使用了内存字节对齐方式优化。
内存字节对齐原则
1、数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int为4字节,则要从4的整数倍地址开始存
储。 min(当前开始的位置mn)m=9n=4 9 10 11 12
2、数据成员为结构体:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)
3、结构体的整体对齐规则:结构体的总大小,即sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐
类型对应的占用字节大小图:
类型占用字节大小图.png
上面几点估计理解起来比较困难,那么我举简单的例子:
struct LNDStruct1 {
double a; //占用8字节
char b; //占用1字节
int c; //占用4字节
short d; //占用2字节
};
如图示意
LNDStruct1内存分布.png
计算步骤为:
-
LNDStruct1结构体中最大属性占用8字节; -
a属性从第[0 7]字节之间存储,理论上下一个属性从第8字节开始存储; - 先判断属性
b占用1个字节,8是1的整数倍,所以第8个字节储存b,理论上下一个属性从第9字节开始存储; - 先判断属性
c占用4个字节,9不是4的整数倍,依次往下推算第10、11字节都不是,第12个字节是,所以第12个字节开始储存属性c,属性c占用字节空间为[12 15],理论上下一个属性从第16字节开始存储; - 先判断属性
d占用2个字节,16是2的整数倍,所以第16个字节开始储存属性d,属性d占用字节空间为[16 17]; -
LNDStruct1结构体中所有属性相加为18个字节空间,根据对齐原则推算出(根据原则第3点),所以LNDStruct1结构体占用字节为24。
接下来我们在上面代码上改变一下,使用结构体嵌套结构体来计算一下
struct LNDStruct2 {
double e; //占用8字节
char f; //占用1字节
int g; //占用4字节
short h; //占用2字节
struct LNDStruct1 st; //占用24个字节
};
如图示意
LNDStruct2内存分布.png
计算步骤为
-
LNDStruct2结构体中最大属性占用8字节; - 根据上面例子的步骤可知属性
e占用字节空间[0 7]、f占用字节空间[8]、g占用字节空间[12 15]、h占用字节空间为[16 17],理论上下一个属性从第18字节开始存储; - 接下来计算
st结构体中属性了- 先判断属性
a占用8个字节,18不是8的整数倍,依次往下推算第19、20、21、22、23字节都不是,第24个字节是,所以第24个字节开始储存属性a,属性a占用字节空间为[24 31],理论上下一个属性从第32字节开始存储; - 先判断属性
b占用1个字节,32是1的整数倍,所以第32个字节开始储存属性b,属性b占用字节空间为第32,理论上下一个属性从第33字节开始存储; - 先判断属性
c占用4个字节,33不是4的整数倍,依次往下推算第34、35字节都不是,第36个字节是,所以第36个字节开始储存属性c,属性c占用字节空间为[36 39],理论上下一个属性从第40字节开始存储; - 先判断属性
d占用2个字节,40是2的整数倍,所以第40个字节开始储存属性d,属性d占用字节空间为[40 41]。
- 先判断属性
-
LNDStruct2结构体中所有属性相加为42个字节空间,(根据原则第3点)所以LNDStruct2结构体占用字节为48。














网友评论