NONPointer_isa 指针中存放与该对象内存相关的消息

苹果将ISA设计成了联合体,在ISA中存储了与该对象相关的一些内存信息,因为 并不需要64个二进制全部都用来存储指针
ISA 的结构

// x86_64 架构
struct {
    uintptr_t nonpointer        : 1;  // 0:普通指针,1:优化过,使用位域存储更多信息
    uintptr_t has_assoc         : 1;  // 对象是否含有或曾经含有关联引用
    uintptr_t has_cxx_dtor      : 1;  // 表示是否有C++析构函数或OC的dealloc
    uintptr_t shiftcls          : 44; // 存放着 Class、Meta-Class 对象的内存地址信息
    uintptr_t magic             : 6;  // 用于在调试时分辨对象是否未完成初始化
    uintptr_t weakly_referenced : 1;  // 是否被弱引用指向
    uintptr_t deallocating      : 1;  // 对象是否正在释放
    uintptr_t has_sidetable_rc  : 1;  // 是否需要使用 sidetable 来存储引用计数
    uintptr_t extra_rc          : 8;  // 引用计数能够用 8 个二进制位存储时,直接存储在这里
};

// arm64 架构
struct {
    uintptr_t nonpointer        : 1;  // 0:普通指针,1:优化过,使用位域存储更多信息
    uintptr_t has_assoc         : 1;  // 对象是否含有或曾经含有关联引用
    uintptr_t has_cxx_dtor      : 1;  // 表示是否有C++析构函数或OC的dealloc
    uintptr_t shiftcls          : 33; // 存放着 Class、Meta-Class 对象的内存地址信息
    uintptr_t magic             : 6;  // 用于在调试时分辨对象是否未完成初始化
    uintptr_t weakly_referenced : 1;  // 是否被弱引用指向
    uintptr_t deallocating      : 1;  // 对象是否正在释放
    uintptr_t has_sidetable_rc  : 1;  // 是否需要使用 sidetable 来存储引用计数
    uintptr_t extra_rc          : 19;  // 引用计数能够用 19 个二进制位存储时,直接存储在这里
};

这里的 has_sidetable_rc 和 extra_rc, has_sidetable_rc 表明了该指针是否引用了sidetable 散列表,之所以有这个选项,是因为少量的引用计数是不会直接存放在SideTables表中的,对象的引用计数会存放在extra_rc 中,当其被存满时,才会存入相应的SideTables 散列表中,SideTable 中有很多张SideTable,每个SideTable 也都是一个散列表,而引用计数表就包含在SideTable之中。

散列表 (引用计数表,弱引用表)
引用计数要么存放在isa 的 extra_rc 中,要么存放在引用计数表中,而引用计数表中包含在一个叫SideTable 的结构中,它是一个散列表,也就是哈希表。而SideTable又包含在一个全局的StripeMap的哈希映射表中,这个表的名字叫SideTables。

当一个对象访问SideTables 时:
1、首先会取得对象的地址,将地址进行哈希运算,与SideTables中的SideTabel的个数取余,最后得到的结果就是该对象所访问的SideTable
2、在取的SideTable 中RefcountMap 表中再进行一次哈希查找。找到该对象在引用计数表中对应的位置。
3、如果该对象存在对应的引用计数,则对其进行操作,如果没有对应的引用计数,则创建一个对应的size_t对象,其实就是一个uint类型的无符号整型。

弱引用表也是一张哈希表的结构,其内部包含了每个对象对应的弱引用表weak_entry_t,而weak_entry_t 是一个结构数组,其中包含的则是每一个对象弱引用的对象对应的弱引用指针。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1、内存布局 stack:方法调用 heap:通过alloc等分配对象 bss:未初始化的全局变量等。 data:...
    AKyS佐毅阅读 5,506评论 0 19
  • iOS中内存管理机制是开发中一项很重要的知识,了解iOS中内存管理的规则不管是在开发中还是在学习中都能很大程度的帮...
    Horson19阅读 5,922评论 0 7
  • iOS中内存管理机制是开发中一项很重要的知识,了解iOS中内存管理的规则不管是在开发中还是在学习中都能很大程度的帮...
    Mr_Atom阅读 8,666评论 1 4
  • 原文链接OC内存管理--引用计数器 更新于2020-02-14 更新Tagged Pointer的知识点 引用计数...
    NeroXie阅读 6,820评论 0 6
  • 第一次写文章语言表达能力太差。如果有哪里表达的不够清晰可以直接评论回复我,我来加以修改。这篇文章力求脱离语言的特性...
    tzhtodd阅读 3,486评论 0 2