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 在调用对 ...
随机推荐
- selenium.common.exceptions.UnexpectedAlertPresentException: Alert Text: None;Message: unexpected alert open: {Alert text : 您点击的频率过快!请稍后再试}
报错 Traceback (most recent call last): File "C:/myFiles/code/cnki/cnki_1/core/knavi.py", li ...
- JAVA中有一个特殊的类: Object。它是JAVA体系中所有类的父类(直接父类或者间接父类)。
接口往往被我们定义成一类XX的东西. 接口实际上是定义一个规范.标准. ① 通过接口可以实现不同层次.不同体系对象的共同属性: 通过接口实现write once as anywhere. 以JA ...
- Linux 用户管理_015
一.用户基础了解 Linux是一个多任务.多用户的操作系统,每个用户和进程都需要对应一个用户和用户组,用户名相当于姓名, 用户UID相当于身份证号,用户组GID相当于公司的工号.用户与用户组的关系一对 ...
- PHP正则验证类
项目中经常使用到的验证,很使用的.查看与下载<?php /** * 验证类 * * @lastmodify 2015-12-19 * @author wuheng */ class Verify ...
- [hive] hive 内部表和外部表
1.内部表 hive (test1)> create table com_inner_person(id int,name string,age int,ctime timestamp) row ...
- k8s(3)-Pods和Nodes的概念
Pod是什么? 在前面创建部署时,Kubernetes创建了一个Pod来托管您的应用程序实例.Pod是一个Kubernetes抽象,表示一组一个或多个应用程序容器(如Docker或rkt),以及这些容 ...
- Java | 原来 serialVersionUID 的用处在这里
本文首发于 http://youngzy.com/ 一直不太明白Java对象里 serialVersionUID 字段是做什么用的.有或者没有,它们之间有差别吗?除了Eclipse里提示的那个黄色的警 ...
- iOS - 数组字典模型根据模型属性key排序
方法一: NSArray *sortArray = [arrayM sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { ...
- yarn配置日志聚合
[原文地址] 日志聚集是YARN提供的日志中央化管理功能,它能将运行完成的Container/任务日志上传到HDFS上,从而减轻NodeManager负载,且提供一个中央化存储和分析机制.默认情况下, ...
- PHP(方法 函数 循环 和 数组 查找)
循环 和 数组 查找 顺序查找 二分法查找 冒泡排序 方法 函数 定义:一堆代码的集合叫做函数(满足条件下“一堆”) 语法,定义,调用,参数列表(形参,实参),返回值 两种方法: function 方 ...