Objective-C RunTime 学习笔记 之 AutoReleasPool
1、结构
- struct magic_t {
- /* 魔法 */
- static const uint32_t M0 = 0xA1A1A1A1;
- # define M1 "AUTORELEASE!"
- static const size_t M1_len = 12;
- uint32_t m[4];
- /* 省略各种方法 */
- # undef M1
- };
- /* AutotRelease 重要:重载了new和delete运算符号,使每个Page对象固定大小 */
- class AutoreleasePoolPage
- {
- #define POOL_SENTINEL nil
- static pthread_key_t const key = AUTORELEASE_POOL_KEY; /* TSD __PTK_FRAMEWORK_OBJC_KEY3 */
- static uint8_t const SCRIBBLE = 0xA3; // 0xA3A3A3A3 after releasing
- static size_t const SIZE =
- #if PROTECT_AUTORELEASEPOOL
- PAGE_MAX_SIZE; // must be multiple of vm page size
- #else
- PAGE_MAX_SIZE; // size and alignment, power of 2 (CGS. 4096 < bytes per 80386 page >)
- #endif
- static size_t const COUNT = SIZE / sizeof(id);
- magic_t const magic;
- id *next; /* objc 对象列表指向下一个未使用的区域 */
- pthread_t const thread; /* page对应线程 */
- /* 链表结构 */
- AutoreleasePoolPage * const parent; /* 父 */
- AutoreleasePoolPage *child; /* 子 */
- uint32_t const depth; /* 链表深度 */
- uint32_t hiwat;
- // SIZE-sizeof(*this) bytes of contents follow
- //省略各种方法
- //00000哨兵分割线
- //各种objc对象,
- }
2、 每个线程对应一个AutoReleasePoolPage 的对象列表
2.1) 线程销毁的时候,释放AutoReleasePoolPage 以及所有对象
2.2) AutoReleasePoolPage 为C++对象,由于重载了new 和 delete 运算符,确保每一个Page分配固定大小(貌似4K)。在类的实例变量/方法列表后存储Foundation对象。而类的next 成员变量则指向下一个Foundation对象。AutoReleasePoolPage 有判断是否为空和满的成员函数,以此来判断当前线程是否新创建一个AutoReleasePool对象。没创建一个对象,都会设置parent、chilid属性,构成双向链表,而hotPage则是存储在线程的本地存储中。系统初始化时会给线程初始化钩子函数 int r __unused = pthread_key_init_np(AutoreleasePoolPage::key, AutoreleasePoolPage::tls_dealloc); 确保在线程销毁的时候,释放AutoReleasePool, 由于hotPage存存在TLS中,并且page为双向链表,可以通过hotPage遍历整个Page俩表,确保释放Page对象。
每个oc对象发送 autorelease 消息或者使用__autorelease 修饰的时候,从当前线程取出hotPage(), 整个函数从线程本地存储中取,如果没有AutoReleasePoolPage链表则创建一个,否则取出AutoReleasePoolPage,查看是否full,如果full则创建一个新的AutoReleasePoolPage,设置parent 和 child属性, 然后设置为hotPage(存入线程中本地存储中 TLS)。
@autoreleasepool {
//some code
}
所有使用 @autoreleasepool block起来的代码,都会在形成
void *pool = AutoReleasePoolPage::push();
//some code
AutoReleasePoolPage::pop(pool);
3、 主线程AutoReleasePoolPage何时pop?
文档中说每个 event loop(鼠标事件、点击事件等)都会在事件的will 时 pool->push(),did时 pool->pop(void *).。OS 会在主线程的RunLoop循环注册一些列观察者,在进入时调用 void *pool = AutoReleasePoolPage::push(); ,退出时调用 AutoReleasePoolPage::pop(pool); 这样子确保每一次循环都进行pool的释放。
Objective-C RunTime 学习笔记 之 AutoReleasPool的更多相关文章
- 我的runtime学习笔记
0.简介: OC方法不同于C语言函数,属于动态调用过程,在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用. 至于其他理论上的东西不必讲太多,编程讲的就 ...
- runtime学习笔记
获取属性objc_property_t * propertys = class_copyPropertyList(clazz, &outCount); 获取属性名NSString * key ...
- iOS Runtime学习笔记
Associated Objects: @interface NSObject (AssociatedObject) @property (nonatomic, strong) id associat ...
- Objective-C学习笔记---构造函数和析构函数
简单的讲,构造函数就是在创建一个对象的时候起到初始化的作用,对这个对象里的一些成员变量进行初始化,析构函数就是在对象被删除进行一些清理工作,也就是专门的扫尾工作,下面用代码来进行具体说明. 一.构造函 ...
- Objective-C RunTime 学习笔记 之 消息转发流程
1) 当向某个对象发送消息时,先从cache(cache_t)中查找方法对象(method_t),如果找到则进行回调:否则通过查找对象的类(元类)定义中方法列表,一直追溯到NSObject, 如果找到 ...
- Objective-C RunTime 学习笔记 之 atomic/nonatomic 关键字
atomic修饰的是变量/方法,对于可变对象的指针变量是安全的,内部实现加了锁,但是对可变对象本身没什么影响,不安全还是不安全.另外atomic仅仅对编译器生产的getter.setter有效,如果自 ...
- Objective-C RunTime 学习笔记 之 基础结构体
1.OC 运行期常用对象结构体 基本的结构体定义 typedef objc_class Class; /* 类 */ typedef objc_object *id; /* 各种类型,只要第一个字段为 ...
- Flink学习笔记:Flink Runtime
本文为<Flink大数据项目实战>学习笔记,想通过视频系统学习Flink这个最火爆的大数据计算框架的同学,推荐学习课程: Flink大数据项目实战:http://t.cn/EJtKhaz ...
- objc_msgSend消息传递学习笔记 – 消息转发
该文是 objc_msgSend消息传递学习笔记 – 对象方法消息传递流程 的基础上继续探究源码,请先阅读上文. 消息转发机制(message forwarding) Objective-C 在调用对 ...
随机推荐
- Dubbo 分布式 日志 追踪
使用dubbo分布式框架进行微服务的开发,一个大系统往往会被拆分成很多不同的子系统,并且子系统还会部署多台机器,当其中一个系统出问题了,查看日志十分麻烦. 所以需要一个固定的流程ID和机器ip地址等来 ...
- Linux网络设备驱动 _驱动模型
Linux素来以其强大的网络功能著名,同时, 网络设备也作为三大设备之一, 成为Linux驱动学习中必不可少的设备类型, 此外, 由于历史原因, Linux并没有强制对网络设备贯彻其"一切皆 ...
- java基础---->java8中的函数式接口
这里面简单的讲一下java8中的函数式接口,Function.Consumer.Predicate和Supplier. 函数式接口例子 一.Function:接受参数,有返回参数 package co ...
- Linux系统挂载windows共享目录报错mount error(121):remote error I/O error
经查,这是由于NFS(Network File System)即网络文件系统服务器有多个版本,V2.V3.V4.而且各版本同时运行,因此挂载时需要说明版本号 mount -o username='pk ...
- 6.2 Pandora 实操 - 数据展示
具体每个图可以到蛋蛋团仪表盘里,查看配置即可.过程中没有截图记下来. 配置方法,建议参考已存在的图表参数,照样配,会比较快. 配置网站访问量 配图结果 参考 报表说明
- hdu 4544——消灭兔子
游戏规则很简单,用箭杀死免子即可. 箭是一种消耗品,已知有M种不同类型的箭可以选择,并且每种箭都会对兔子造成伤害,对应的伤害值分别为Di(1 <= i <= M),每种箭需要一定的QQ币 ...
- ubuntu下安装go环境
1.官网下载go语言安装包 地址:https://studygolang.com/dl 2.服务器上安装go 将下载下来的安装包解压到/usr/local下 tar xf go1.12.1.linux ...
- vue2.0 源码解读(一)
又看完一遍中文社区的教程接下来开始做vue2.0的源码解读了! 注:解读源码时一定要配合vue2.0的生命周期和API文档一起看 vue2.0的生命周期分为4主要个过程 create. 创建---实例 ...
- 解决秒杀活动高并发出现负库存(Redis)
商城在秒杀活动开始时,同时有好多人来请求这个接口,即便做了判断库存逻辑,也难免防止库存出现超卖,造成损失 Django中的ORM本身就对数据库做了防范,但再过亿级访问也扛不住 下面利用Redis的过载 ...
- JQuery插件之【jqGrid】常用语法整理
jqGrid常用语法整理,包含数据获取.常用函数.触发事件等 jqGrid表格数据获取相关语法 获取表格所有数据 $("#grid").jqGrid("getRowDat ...