这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战 上文咱们俩节了内存对齐的一些内容,今天来继续学习。markdown
已知系统会根据数据类型跳过部份内存,那跳过的部分为何不能存储数据?函数
如上图所示,对于不优化连续存储的状况,CPU
读取8~15
的内存数据,须要先读取1字节再读取4字节
,CPU对于要读取的数据大小是有变化的。而优化后CPU先读取4字节(因为白色3字节空白因此能够直接读取4字节)再读取4字节
再这段内存中是没有变化的。相比于第一种状况,优化后CPU要进行的操做变少了,这就实现了通过空间换取时间
。post
分析了内存对齐原理,下面咱们来看一下系统是如何开辟内存的。学习
PDObject
定义以下:优化
@interface PDObject : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) long height;
@end
复制代码
调用:atom
#import "PDObject.h"
#import <objc/runtime.h>
#import <malloc/malloc.h>
PDObject *pdObj = [PDObject alloc];
pdObj.name = @"HotpotCat";
pdObj.age = 18;
NSLog(@"sizeof:%zu class_getInstanceSize:%zu malloc:%zu",sizeof(pdObj),class_getInstanceSize([PDObject class]),malloc_size((__bridge const void *)(pdObj)));
复制代码
那么sizeof、class_getInstanceSize、malloc_size分别输出多少呢? 验证:spa
sizeof:8 class_getInstanceSize:40 malloc:48
复制代码
pdObj
是一个结构体指针sizeof
返回8
。class_getInstanceSize
因为存在isa
和8字节对齐
因此返回40 。malloc_size
为何返回48
呢?在系统的内存堆区中对象的内存是16字节对齐,成员变量是以8字节对齐(结构体内部)。对象与对象是16字节对齐。3d
为何对象不以8字节对齐?而以16字节对齐?指针
假如一个对象内部成员变量都是8字节大小。code
对于64字节的空间:
16 32 48 64
8 16 24 32 40 48 56 64
复制代码
以8字节对齐须要访问8次,以16字节对齐须要访问4次
NSObject
,可是不多有对象只有一个isa
。因此最小的对象都应该是16。sizeof
:是运算符,不是函数。获取对象的长度(对象自己)。class_getInstanceSize
:获取类的实例所占用的内存大小。大小只与成员变量有关。malloc_size
:alloc中实际开辟的空间。calloc
16字节对齐,最小返回16.
segregated_size_to_fit
中。以16字节对齐向上取整