影响对象内存的因素
对象⾥⾯存储了⼀个isa指针 + 成员变量的值,isa指针是固定的,占8个字节,所以影响对象内存
的只有成员变量(属性会⾃动⽣成带下划线的成员变量)
对象的内存分布
在对象的内部是以8字节进⾏对⻬的。
苹果会⾃动重成员变量的顺序,将占⽤不⾜ 8 字节的成员挨在⼀起,凑满 8 字节,以达到优化内
存的⽬的。
联合体(union)
联合体⼜叫共⽤体,union就是在内存中划了⼀个⾜够⽤的空间,⾄于你怎么玩~它不管~!联合体
的成员变量就相当于为这块内存空间开辟了⼏个访问途径,他们共享这⼀块内存。
联合体的⼤⼩计算奉⾏俩个规则
1.联合体⼤⼩必须能容纳联合体中最⼤的成员变量
2.通过1计算出的联合体⼤⼩必须是联合体中占内存⼤⼩最⼤的基本数据类型⼤⼩的整数倍
联合体和结构体的区别
结构体(struct)中所有变量是“共存”的,⽽联合体(union)中是各变量是“互斥”的,只能存在⼀个。
struct内存空间的分配是粗放的,不管⽤不⽤,全部分配。这样带来的⼀个坏处就是对于内存的消
耗要⼤⼀些。但是结构体⾥⾯的数据是完整的。
联合体⾥⾯的数据只能存在⼀个,但优点是内存使⽤更为精细灵活,也节省了内存空间。
位域
位域的宽度不能超过前⾯数据类型的最⼤⻓度,⽐如int占4个字节也就是32位,那后⾯的数字就不
能超过32。
⼀个位域存储在同⼀个字节中,如⼀个字节所剩空间不够存放另⼀位域时,则会从下⼀单元起存放
该位域。
位域能够节省⼀定的内存空间。
nonPointerIsa
nonPointerIsa是内存优化的⼀种⼿段。isa是⼀个Class类型的结构体指针,占8个字节,主要是⽤
来存内存地址的。但是8个字节意味着它就有8*8=64位。存储地址根本不需要这么多的内存空间。
⽽且每个对象都有个isa指针,这样就浪费了内存。所以苹果就把和对象⼀些息息相关的东⻄,存
在了这块内存空间⾥⾯。这种isa指针就叫nonPointerIsa。
nonPointerIsa存储的内容有:
isa指针的数据结构
arm64 (模拟器)
uintptr_t nonpointer : 1;
uintptr_t has_assoc : 1;
uintptr_t weakly_referenced : 1;
uintptr_t shiftcls_and_sig : 52;
uintptr_t has_sidetable_rc : 1;
uintptr_t extra_rc : 8
arm64 (真机)
uintptr_t nonpointer : 1;
uintptr_t has_assoc : 1;
uintptr_t has_cxx_dtor : 1;
uintptr_t shiftcls : 33;
uintptr_t magic : 6;
uintptr_t weakly_referenced : 1;
uintptr_t unused : 1;
uintptr_t has_sidetable_rc : 1;
uintptr_t extra_rc : 19
x86_64
uintptr_t nonpointer : 1;
uintptr_t has_assoc : 1;
uintptr_t has_cxx_dtor : 1;
uintptr_t shiftcls : 44;
uintptr_t magic : 6;
uintptr_t weakly_referenced : 1;
uintptr_t unused : 1;uintptr_t has_sidetable_rc : 1;
uintptr_t extra_rc : 8