- AutoRelease 是依靠 AutoreleasePoolPage 来进行 push 和 pop 进行工作的
- AutoreleasePoolPage 为双向链表,parent 字段指向上一层,child 指向下一层
- 每个 AutoreleasePoolPage 的大小为 4096 字节
- 每个 AutoreleasePoolPage 最多可以存放 505 个对象。首个 page 可以存储 504 个对象要创建一个哨兵对象。
- AutoreleasePool 和 线程是一一对应的。
- hotpage: 是指当前正在使用的 page
Q. 为什么 AutoreleasePoolPage 最多存放 505 个对象。
AutoreleasePoolPageData 结构体占了 56 个字节。其中
* magic:16 字节。(为一个结构体,用来验证 AutoreleasePoolPage 完整性)
* next :8 字节。(添加时,记录Autorelease 对象的下一个位置)
* parent:8 字节。(记录上一个page)
* child:8 字节。(记录下一个 page)
* thread:8 字节。(当前 AutoreleasePool 所在的线程,AutoreleasePool和线程对应)
* depth:4 字节。(记录节点深度)
* hiwat:4 字节。
剩余容量:4096-16-48-24 = 4040
最大存储对象数量:4040/8 = 505
当 page 为首个的时候,需要创建一个 pool 哨兵对象,占 8 字节。所以为 504 个
Q. AutoreleasePool 和 Runloop 的关系
再 app 启动后 Runloop 会注册很多 observers,其中就有和 AutoreleasePool 相关的。
- 即将进入 Runloop 时,进行调用
_objc_autoreleasePoolPush
创建AutoreleasePool
- runloop 即将睡眠时,执行
_objc_autoreleasePoolPop
来释放旧的释放池,同时_objc_autoreleasePoolPush
创建一个新的,用来添加唤醒后需要处理的 - runloop 即将退出时,执行
_objc_autoreleasePoolPop
来释放