iOS:AutoReleasePool

发布时间 2023-04-21 13:43:24作者: dulinshun

具体参考文章

  1. AutoRelease 是依靠 AutoreleasePoolPage 来进行 push 和 pop 进行工作的
  2. AutoreleasePoolPage 为双向链表,parent 字段指向上一层,child 指向下一层
  3. 每个 AutoreleasePoolPage 的大小为 4096 字节
  4. 每个 AutoreleasePoolPage 最多可以存放 505 个对象。首个 page 可以存储 504 个对象要创建一个哨兵对象。
  5. AutoreleasePool 和 线程是一一对应的。
  6. 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来释放