Apple内存布局
一、Objective-C1.获取内存大小方法2.struct内存对齐3.class内存对齐
二、Swift三、内存对齐1.什么是内存对齐2.内存对齐的原则3.内存对齐的原因
四、面试问题问题:
一、Objective-C
结构体和类的内存布局。 iOS设备的处理器是基于ARM架构的, 默认采用的是小端模式(即低字节放低位)
1.获取内存大小方法
sizeofclass_getInstanceSizemalloc_size
// 这是一个操作符,课操作的数据有基本数据类型、指针、对象。由于它不是函数,所以在编译时就确定了大小
sizeof
// 获取实例变量的成员变量大小之和,8字节对齐,用之前需要导入头文件objc/runtime.h
class_getInstanceSize
// 获取系统实际开辟的内存大小,用之前需导入头文件malloc/malloc.h
malloc_size
2.struct内存对齐
定义一个结构体,苹果标准写法需要typedef重新命名 结构体包含1个int型age,一个double型height
struct Objective {
int age; // 4个字节
double height; // 8个字节
};
typedef struct Objective ObjectiveStruct;
对刚刚定义的结构体测试:
Input:
NSLog(@"ObjectiveStruct Size: %zd", sizeof(ObjectiveStruct));
Output:
ObjectiveStruct Size: 16
分析ObjectiveStruct:
(1).输出结果是16,也就是说我们定义的这个结构体占16个字节
(2).age是int类型,占4个字节
(3).height是double类型,占8个字节,并且要从8的整数倍开始存取,所以age后面还需要补4个字节
(5).所以ObjectiveStruct总共占用内存大小是:4(age)+4(空)+8=16
3.class内存对齐
定义一个ObjectiveObject class 结构体包含1个int型age,一个double型height
@interface ObjectiveObject : NSObject
@property int age; // 4个字节
@property double height; // 8个字节
// 对象占用内存大小:8字节对齐,最小16(class_getInstanceSize) 16+8=24
// 系统实际分配的内存大小:16字节对齐(malloc_size) 16+16 = 32
// 面试题:一个NSObject对象占用多少内存?
// 在64位架构下, 系统分配了16个字节给NSObject对象(通过malloc_size函数获得);
// 但NSObject对象内部只使用了8个字节的空间(可以通过class_getInstanceSize函数获得)。
@end
对刚刚定义的类测试:
Input:
ObjectiveObject *obj = [[ObjectiveObject alloc] init];
size_t instanceSize = class_getInstanceSize(obj.class);
size_t realSize = malloc_size((__bridge const void *)(obj));
NSLog(@"sizeof Size: %zd", sizeof(obj));
NSLog(@"ObjectiveObject Size: %zd", instanceSize);
NSLog(@"realSize Size: %zd", realSize);
Output:
sizeof Size: 8
ObjectiveObject Size: 24
realSize Size: 32
分析ObjectiveStruct:
(1).输出结果是16,也就是说我们定义的这个结构体占16个字节
(2).age是int类型,占4个字节
(3).height是double类型,占8个字节,并且要从8的整数倍开始存取,所以age后面还需要补4个字节
(5).所以ObjectiveStruct总共占用内存大小是:4(age)+4(空)+8=16
二、Swift
待完善
三、内存对齐
1.什么是内存对齐
在计算机中,内存大小的基本单位是字节,理论上来讲,可以从任意地址访问某种基本数据类型。 但是实际上,计算机并非按照字节大小读写内存,而是以2、4、8的倍数的字节块来读写内存。因此,编译器会对基本数据类型的合法地址作出一些限制,即它的地址必须是2、4、8的倍数。那么就要求各种数据类型按照一定的规则在空间上排列,这就是对齐。 在iOS,iPadOS,MacOS开发过程中,编译器会自动的进行字节对齐的处理,并且在64位架构下,是以8字节进行内存对齐的。
2.内存对齐的原则
32位下采用4字节对齐,64位下采用8字节对齐
(1).数据成员对齐规则,结构体或者联合体的第一个成员放在offset为0的地方,
以后每个数据成员存储的起始位置要从该成员的大小或者该成员的子成员的大小的整数倍开始
(2).结构体作为成员:如果一个结构体A中有结构体B作为子成员,B中存放有char,int,double等元素,
那么B应该从double也就是8的整数倍开始存储
(3).结构体的总体大小,即sizeof的结果,必须是其内部最大成员的整数倍,不足的需要补齐.
3.内存对齐的原因
四、面试问题
struct Objective {
int age;
double height;
};
typedef struct Objective ObjectiveStruct;
@interface ObjectiveObject : NSObject
@property int age;
@property double height;
@end
问题:
1.ObjectiveStruct这个结构体和ObjectiveObject这个类占用多少内存空间? ObjectiveStruct:16 ObjectiveObject:32 2.一个NSObject对象占用多少内存? 在64位架构下, 系统分配了16个字节给NSObject对象(通过malloc_size函数获得); 但NSObject对象内部只使用了8个字节的空间(可以通过class_getInstanceSize函数获得)。 对象占用内存大小:8字节对齐,最小16(class_getInstanceSize)。 系统实际分配的内存大小:16字节对齐(malloc_size)
推荐链接
发表评论