美文网首页
(引用计数表和weak表)散列表

(引用计数表和weak表)散列表

作者: Shineyok | 来源:发表于2021-12-01 16:31 被阅读0次

散列表

 散列表其实是一个哈希表,下面挂载了64张表,每张表都包含自旋锁,引用计数表,弱引用表
  • 自旋锁:忙等,如果锁已被其他线程获取,那么当前线程会自己去不断的获取是否被释放,直到其他线程释放,适用于轻量访问,如+1,-1。
  • 引用计数表:hash查找,提高查找效率,插入和查找通过同一个hash函数来获取,避免了循环遍历。ptr->hash->size_t,其中的size_t就是引用计数值,比如用64位存储,第一位表示(weakly_referenced),表示对象是否存在弱引用,下一位表示当前对象是都正在dealoc(deallocating),剩下的位表示引用计数值。
  • 弱引用表:也是一个hash表,key->hash查找->weak_entry_t,weak_entry_t其实是一个结构体数组(weakPtr),比如被weak修饰,就存在这个弱引用表中。

引用计数存储

如果引用计数小于19个二进制位,则存储在isa指针的extra_rc;如果引用计数过大,则isa中的has_sidetable_rc就为1,引用计数就存储在一个叫SideTable的结构体的refcnts成员中,refcnts是个散列表。

ARC即自动引用计数

使用ARC应遵循原则

  • 不能使用retain、release、autorelease、retainCount
  • 不能使用NSAllocateObject以及NSDeallocateObject
  • 必须遵循内存管理方法的命名规则
  • 不需要显式调用dealloc
  • 不能使用NSZone
  • 对象型变量不能作为C结构体成员
  • 显式转换id以及void*

ARC自动内存管理原则———谁持有谁释放

  • 自己生成的自己可以持有
  • 非自己生成的自己可以持有
  • 自己持有的不再需要时自己要对其释放
  • 非自己持有的对象自己无法对其释放

weak

weak实现

Runtime维护了一个全局的CFMutableDictionary,来保存对象的weak指针列表。key为所指对象的内存地址,由于每个对象可能有多个weak指针,value则为weak指针的地址集合(CFMutableSet类型)。

weak实现原理

  • 初始化时:runtime调用objc_initWeak函数,objc_initWeak函数会初始化一个新的weak指针指向对象地址。

    objc_initWeak函数有一个前提条件:就是object必须是一个没有被注册为__weak对象的有效指针。而value则可以是null,或者指向一个有效的对象

  • 添加引用时:objc_initWeak函数调用objc_storeWeak()函数,objc_storeWeak()的作用是更新指针指向,创建对应的弱引用表(新旧表比对)

  • 释放时:调用clearDeallocating函数。clearDeallocating先根据对象地址获取所有weak指针的集合,然后遍历集合将其中数据设为nil,最后把这个entry从weak表删除,最后做清理的记录

    当weak引用的对象被释放时,对于weak指针的处理流程如下:

    1. 调用objc_release
    2. 由于引用计数为0,执行dealloc
    3. dealloc中调用_objc_rootDealloc
    4. _objc_rootDealloc中调用object_dispose
    5. 调用objc_destructInstance
    6. 调用objc_clear_deallocating,objc_clear_deallocating流程如下:
      1. 从weak表中,以dealloc对象为key,找到对应weak_entry_t集合
      2. 将weak_entry_t集合中的所有附有 weak修饰符变量的地址,赋值为nil
      3. 将weak表中该对象移除

相关文章

  • 04内存管理

    小对象非指针类型散列表(引用计数表和弱引用表)

  • (引用计数表和weak表)散列表

    散列表 自旋锁:忙等,如果锁已被其他线程获取,那么当前线程会自己去不断的获取是否被释放,直到其他线程释放,适用于轻...

  • 5.ARC 的 retainCount 怎么存储的?

    存在64张哈希表中,根据哈希算法去查找所在的位置,无需遍历,十分快捷 散列表(引用计数表、weak表) SideT...

  • iOS日记4-weak关键字

    1.runtime中如何实现weak 生成weak对象 weak对象有一张weak表(类似引用计数表),是作为散列...

  • iOS ,内存分布、内存管理 、isa 指针,散列表(引用计数表

    iOS ,内存分布、内存管理 、isa 指针,散列表(引用计数表,弱引用表) 内存管理方案 1.taggedPoi...

  • 内存管理(中)

    散列表结构分析 散列表本质就是一张哈希表,散列表的类型是SideTable,有如下定义 包含一把锁、一张引用计数表...

  • iOS底层-- weak修饰对象存储原理

    问题:为何weak修饰的变量可以打破循环引用?因为weak修饰的变量存储在散列表中的弱引用表里,不参与引用计数器的...

  • weak原理概括

    weak底层千千万,吾竟装作看不见... weak基本用法 weak是弱引用,用weak描述修饰或者所引用对象的计...

  • 【iOS】weak的底层实现

    weak底层千千万,吾竟装作看不见... weak基本用法 weak是弱引用,用weak描述修饰或者所引用对象的计...

  • 新增总结

    1.问:系统根据不同场景下提供的内存管理方案有哪些?1.答:散列表,是一个复杂的数据结构。(包括引用计数表和弱引用...

网友评论

      本文标题:(引用计数表和weak表)散列表

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