iOS - 引用计数(ARC)

1. 基本数据结构

// 对象结构
struct objc_object {isa_t isa;  // isa 指针,包含引用计数信息
};// isa 的位域结构
union isa_t {uintptr_t bits;struct {uintptr_t nonpointer        : 1;  // 是否启用优化的 isa 指针uintptr_t has_assoc         : 1;  // 是否有关联对象uintptr_t has_cxx_dtor      : 1;  // 是否有 C++ 析构函数uintptr_t shiftcls          : 33; // 类的指针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; // 额外的引用计数值};
}

2. 引用计数存储位置

2.1 isa 优化

inline bool 
objc_object::hasNonpointerIsa() {return isa.nonpointer;  // 判断是否使用优化的 isa
}// 引用计数存储在 isa 的情况
if (isa.nonpointer) {// 引用计数存储在 isa.extra_rc 中// 最多可存储 2^19 - 1 个引用
}

2.2 SideTable 存储

struct SideTable {spinlock_t slock;RefcountMap refcnts;  // 引用计数哈希表weak_table_t weak_table;  // 弱引用表
};// 当 isa 中的引用计数溢出时
if (isa.has_sidetable_rc) {// 引用计数存储在 SideTable 的 refcnts 中
}

3. 引用计数操作

3.1 retain 操作

id objc_retain(id obj) {if (!obj) return obj;if (obj->isTaggedPointer()) return obj;return obj->retain();
}inline id 
objc_object::retain() {if (isTaggedPointer()) return this;if (fastpath(!ISA()->hasCustomRR())) {if (fastpath(isa.hasNonpointerIsa())) {addExtraRC_nolock();} else {sidetable_retain();}}return this;
}

3.2 release 操作

void objc_release(id obj) {if (!obj) return;if (obj->isTaggedPointer()) return;obj->release();
}inline bool 
objc_object::release() {if (isTaggedPointer()) return false;if (fastpath(!ISA()->hasCustomRR())) {if (fastpath(isa.hasNonpointerIsa())) {return sidetable_release(true);}return sidetable_release(false);}return false;
}

4. 引用计数溢出处理

void objc_object::sidetable_addExtraRC_nolock(size_t delta_rc) {// 当 isa.extra_rc 即将溢出时if (isa.extra_rc + delta_rc > RC_MASK) {// 将引用计数迁移到 SideTableisa.has_sidetable_rc = true;auto &table = SideTables()[this];size_t& refcnt = table.refcnts[this];refcnt += delta_rc;} else {// 继续使用 isa 存储isa.extra_rc += delta_rc;}
}

5. 弱引用处理

5.1 弱引用表结构

struct weak_table_t {weak_entry_t *weak_entries;  // 弱引用数组size_t    num_entries;       // 条目数uintptr_t mask;             // 容量掩码uintptr_t max_hash_displacement;  // 最大哈希偏移
};

5.2 弱引用操作

id objc_loadWeakRetained(id *location) {id obj = *location;if (!obj) return nil;if (obj->isTaggedPointer()) return obj;return obj->rootRetain();
}void objc_storeWeak(id *location, id obj) {_objc_weak_store(location, obj);
}

6. 自动释放池相关

void *objc_autoreleasePoolPush(void) {return AutoreleasePoolPage::push();
}void objc_autoreleasePoolPop(void *ctxt) {AutoreleasePoolPage::pop(ctxt);
}id objc_autorelease(id obj) {if (!obj) return obj;if (obj->isTaggedPointer()) return obj;return obj->autorelease();
}

7. 优化机制

7.1 Tagged Pointer

bool isTaggedPointer() {return ((uintptr_t)this & _OBJC_TAG_MASK) == _OBJC_TAG_MASK;
}// Tagged Pointer 对象不参与引用计数
if (obj->isTaggedPointer()) {return obj;  // 直接返回,不进行引用计数操作
}

7.2 散列表优化

// SideTable 的哈希表实现
struct RefcountMap : public objc::DenseMap<DisguisedPtr<objc_object>,size_t,true> {// 使用 DenseMap 提高查找效率
};

8. 内存管理策略

8.1 dealloc 流程

inline void 
objc_object::rootDealloc() {if (isTaggedPointer()) return;if (fastpath(isa.hasNonpointerIsa())) {// 快速释放路径if (fastpath(!isa.weakly_referenced && !isa.has_assoc)) {free(this);return;}}object_dispose((id)this);
}

8.2 引用计数检查

bool objc_object::rootTryRetain() {if (isTaggedPointer()) return true;if (fastpath(!ISA()->hasCustomRR())) {if (fastpath(isa.hasNonpointerIsa())) {// 尝试增加引用计数return sidetable_tryRetain();}}return false;
}

这个引用计数系统的设计考虑了:

  1. 性能优化(isa 优化、Tagged Pointer)
  2. 内存效率(分散存储策略)
  3. 线程安全(自旋锁、原子操作)
  4. 扩展性(支持自定义引用计数)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/66421.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

尚硅谷· vue3+ts 知识点学习整理 |14h的课程(持续更ing)

vue3 主要内容 核心&#xff1a;ref、reactive、computed、watch、生命周期 常用&#xff1a;hooks、自定义ref、路由、pinia、miit 面试&#xff1a;组件通信、响应式相关api ----> 笔记&#xff1a;ts快速梳理&#xff1b;vue3快速上手.pdf 笔记及大纲 如下&#xff…

【Ubuntu20.04】Apollo10.0 Docker容器部署+常见错误解决

官方参考文档【点击我】 Apollo 10.0 版本开始&#xff0c;支持本机和Docker容器两种部署方式。 如果您使用本机部署方式&#xff0c;建议使用x86_64架构的Ubuntu 22.04操作系统或者aarch64架构的Ubuntu 20.04操作系统。 如果您使用Docker容器部署方式&#xff0c;可以使用x…

安卓14无法安装应用解决历程

客户手机基本情况&#xff1a; 安卓14&#xff0c;对应的 targetSdkVersion 34 前天遇到了安卓14适配问题&#xff0c;客户发来的截图是这样的 描述&#xff1a;无法安装我们公司的B应用。 型号&#xff1a;三星google美版 解决步骤&#xff1a; 1、寻找其他安卓14手机测试…

利用 NineData 实现 PostgreSQL 到 Kafka 的高效数据同步

记录一次 PostgreSQL 到 Kafka 的数据迁移实践。前段时间&#xff0c;NineData 的某个客户在一个项目中需要将 PostgreSQL 的数据实时同步到 Kafka。需求明确且普遍&#xff1a; PostgreSQL 中的交易数据&#xff0c;需要实时推送到 Kafka&#xff0c;供下游多个系统消费&#…

Zookeeper是如何保证事务的顺序一致性的?

大家好&#xff0c;我是锋哥。今天分享关于【Zookeeper是如何保证事务的顺序一致性的?】面试题。希望对大家有帮助&#xff1b; Zookeeper是如何保证事务的顺序一致性的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Zookeeper 通过多个机制来保证事务的顺序一…

电脑如何无线控制手机?

想在电脑上无线控制手机&#xff0c;需要用到Total Control控制软件&#xff0c;具体步骤如下&#xff1a; 1、首先我们在电脑上安装上控制软件Total Control并打开。 2、开启手机USB调试和ADB仅充电模式。 3、手机电脑均连接上相同局域网。 4、连接(首次使用需要用手机U…

内网穿透的应用-自托管文件分享系统PicoShare搭建流程与远程共享实战教程

文章目录 前言1. 本地安装Docker2. 本地部署PicoShare3. 如何使用PicoShare4. 公网远程访问本地 PicoShare4.1 内网穿透工具安装4.2 创建远程连接公网地址 5. 固定PicoShare公网地址 前言 大家好&#xff01;在数字化时代&#xff0c;文件共享变得越来越重要&#xff0c;尤其是…

STM32 拓展 电源控制

目录 电源控制 电源框图 VDDA供电区域 VDD供电区域 1.8V低电压区域 后备供电区域 电压调节器 上电复位和掉电复位 可编程电压检测器(PVD) 低功耗 睡眠模式(只有CUP(老板)睡眠) 进入睡眠模式 退出睡眠模式 停机(停止)模式(只留核心区域(上班)) 进入停…

欧几里得距离在权重矩阵中的物理意义

欧几里得距离在权重矩阵中的物理意义 目录 欧几里得距离在权重矩阵中的物理意义**衡量神经元差异程度**:**反映模型变化程度**:**聚类和分组的依据**:自然语言处理中的模型更新:**神经网络聚类分组**:欧几里得距离在权重矩阵中的物理意义衡量神经元差异程度: 在神经网络中…

pytorch中nn.Conv2d详解及参数设置原则

文章目录 基础参数1. in_channels (输入通道数)2. out_channels (输出通道数)3. kernel_size (卷积核大小)4. stride (步幅)5. padding (填充)6. dilation (膨胀)7. groups (分组卷积)8. bias (偏置) 如何设置参数&#xff1f;1. **in_channels 和 out_channels&#xff08;输入…

GolangWeb开发- net/http模块

文章目录 Golang开发-案例整理汇总一、net/http介绍二、HTTP客户端Get请求Post请求三、HTTP服务端总结Golang开发经典案例,点击下方链接 Golang开发-案例整理汇总 一、net/http介绍 Go语言内置的net/http包提供了HTTP客户端和服务端的实现。 文档链接: https://pkg.go.dev/n…

内蒙古水系详细很全shp格式arcgis软件无偏移坐标下载后内容测评

标题中的“内蒙古水系详细很全shp格式arcgis软件无偏移坐标”指的是一个地理信息系统&#xff08;GIS&#xff09;数据集&#xff0c;该数据集详细记录了内蒙古地区的水系信息&#xff0c;并以ESRI公司的标准矢量数据格式——Shapefile&#xff08;.shp&#xff09;进行存储。S…

【Vim Masterclass 笔记07】S05L19:Vim 剪切、复制、粘贴操作同步练习

文章目录 S05L19 Vim 剪切、复制、粘贴操作同步练习&#xff08;Exercise 05 - Cut, Copy and Paste&#xff09;1 训练目标2 操作指令2.1 打开 dyp.txt 文件2.2 交换文件的头两行2.3 将文件首行 put 到文件其他为止2.4 练习在光标位置的上方粘贴文本行2.5 通过交换字符顺序更正…

【Rust自学】10.6. 生命周期 Pt.2:生命周期的语法与例子

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 10.6.1. 生命周期标注语法 生命周期的标注并不会改变引用的生命周期长度。如果某个函数它制定了泛型生命周期参数&#xff0c;那么它就可…

HTML 显示器纯色亮点检测工具

HTML 显示器纯色亮点检测工具 相关资源文件已经打包成html等文件&#xff0c;可双击直接运行程序&#xff0c;且文章末尾已附上相关源码&#xff0c;以供大家学习交流&#xff0c;博主主页还有更多Html相关程序案例&#xff0c;秉着开源精神的想法&#xff0c;望大家喜欢&#…

服务器虚拟化:现代 IT 基础架构的核心技术

服务器虚拟化&#xff1a;现代 IT 基础架构的核心技术 随着云计算和大规模数据中心的快速发展&#xff0c;服务器虚拟化已成为现代 IT 基础架构中的核心技术。通过虚拟化&#xff0c;企业可以在同一台物理服务器上运行多个虚拟机&#xff08;VM&#xff09;&#xff0c;从而提…

晨辉面试抽签和评分管理系统之一:考生信息管理和编排

晨辉面试抽签和评分管理系统&#xff08;下载地址:www.chenhuisoft.cn&#xff09;是公务员招录面试、教师资格考试面试、企业招录面试等各类面试通用的考生编排、考生入场抽签、候考室倒计时管理、面试考官抽签、面试评分记录和成绩核算的面试全流程信息化管理软件。提供了考生…

PHP7和PHP8的最佳实践

php 7 和 php 8 的最佳实践包括&#xff1a;使用类型提示以避免运行时错误&#xff1b;利用命名空间组织代码并避免命名冲突&#xff1b;采用命名参数、联合类型等新特性增强可读性&#xff1b;用错误处理优雅地处理异常&#xff1b;关注性能优化&#xff0c;如避免全局变量和选…

Hadoop、Flink、Spark和Kafka

Hadoop、Flink、Spark和Kafka是大数据处理领域中的四个重要工具&#xff0c;它们在架构、数据处理方式以及性能等方面都存在区别。以下是具体分析&#xff1a; 架构 Hadoop&#xff1a;Hadoop的核心是HDFS&#xff08;Hadoop Distributed File System&#xff09;和MapReduce编…

C++和OpenGL实现3D游戏编程【2.1】——游戏基类Object的构建

欢迎来到zhooyu的专栏。 主页网址:【zhooyu】 专栏网址:【C++和OpenGL实现3D游戏编程】 🌟🌟🌟这里将通过一个OpenGL实现3D游戏编程实例教程,带大家深入学习OpenGL知识。知识无穷而人力有限,专题能够帮助您在有限的时间内快速了解并掌握OpenGL编程,深入掌握知识精华…