一个 oc 对象实际占用的内存大小是其所有数据成员所占内存大小之和
64 位架构之下,int 类型占 4 个字节,long 类型占 8 个字节,BOOL 类型占 1 个字节,float 类型占 4 个字节,double 类型占 8 个字节,void *类型(对象指针占 8 个字节)
但是为了提高 cpu 的内存存取效率,oc 对象的机构提需要进行内存对齐,结构体内存对齐规则如下
1.第一个数据成员的起始位置位 0,后续数据成员的起始位置是该数据成员所占内存大小的整数倍;
2.如果数据成员是一个结构体,则该结构体数据成员的起始位置是该结构体数据成员中数据成员的最大内存大小的整数倍;
NSObject 对象包含一个 void * 类型的 isa,随意 NSObject 对象占用 8 个字节的内存.
由于系统是以 16 字节为单位来分配内存的,小于 16 字节就分配 16 字节,大于 16 字节就会分配 16 字节的整数倍大小,所以 NSObject 最后会占用 16 字节的内存大小
OC 对象的结构体中的数据成员的顺序:
1.首先是父类对象结构体
2.然后是自己本身的数据成员,按所占内存大小从小到大进行排列.
所以 OC 对象对应的结构体第一个数据成员始终是 isa 指针
没代码还比比个毛线呀~~~
由 oc 源码可以看出,如果分配的内存小于 16 个字节,则直接设置为 16 字节
接下来我可以通过内存工具来测试一下 debug 模式,shift + command + M(查看memory)
可以看出,第一行的前 8 个字节是有值的,而后面 8 个字节 全是 00,说明只使用到了前 8 个字节
也可以使用 x 命令查看得到同样的结论
可以测试一下自定义的对象
像上面这个对象,里面有3个属性,都是int ,每个int类型是占4字节的,具体其它类型占多少可以去查官方文档
同过如下代码进行测试:
通过内存打印,可以看得出3个属性分别各自占用了4个字节,总共是24个,那为什么malloc_size 会输出32个呢?
原因就是系统底层的内存对齐导致的 (内存对齐分配的16的倍数,像24不是16的倍数,所以被分配32)
通过上面这个输出日志可以看得出,如果我们这个DSPerson只有2个属性,那它的分配大小和实际占用大小应该都是16,因为NSObject对象默认只用到了前8个字节