美文网首页
NONPointer_isa 指针中存放与该对象内存相关的消息

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

作者: TaoGeNet | 来源:发表于2020-03-01 21:55 被阅读0次

苹果将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 是一个结构数组,其中包含的则是每一个对象弱引用的对象对应的弱引用指针。

相关文章

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

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

  • 【前端学习笔记】JS引用类型——引用栈中的一地址

    引用类型是存放在堆内存中的对象。 引用类型是存放在堆内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置...

  • js 对象深拷贝与浅拷贝

    js基本数据类型与对象指针(引用地址)存放在栈内存,对象实际存放在堆内存。变量标志符和值(基本数据和指针)保存在栈...

  • 15章:内存与对象

    对象与内存 15.1指针和指针的值 对象只能通过指针访问,所以人们常用指向对象的指针来称呼该对象,例如有时候说“n...

  • Java基础---内存中的对象与对象引用

    其实引用这种机制就像C语言中的指针,在一块内存中存放一个指针类型的变量,另一块内存存放一个与指针数据类型相同的变量...

  • C语言关于指针与指针变量的总结

    指针 一个变量的内存地址称为该变量的“指针”。(指针 即 地址) 存放指针的变量称为"指针变量"。(指针变量 即 ...

  • 【Objective-C笔记】—— 对象1

    创建对象 向Party类发送alloc消息,该类收到alloc消息后,在内存中创建对象,并返回指向新对象的指针,新...

  • iOS日记-浅拷贝和深拷贝

    什么是浅拷贝和深拷贝? 浅拷贝是拷贝了指向对象的指针, 深拷贝不但拷贝了对象的指针,还在系统中再分配一块内存,存放...

  • 深入理解了指针的概念

    指针,只对内存有用。内存中按序列存放了 单位数量的字节也就是信息。而指针,指向了内存中这些序列 示例。

  • 手写cloneDeep

    我们都知道引用类型其实是在栈内存中存储了一个指针,这个指针指向堆内存中该对象的存储地址。复制给另一个对象的过程其实...

网友评论

      本文标题:NONPointer_isa 指针中存放与该对象内存相关的消息

      本文链接:https://www.haomeiwen.com/subject/mbnlkhtx.html