AutoReleasePool

AutoReleasePool

AutoReleasePool是用来自动释放调用了autoRelease的对象,通过runloop 开始进入runloop,即将休眠,即将退出runloop的时候开始处理AutoReleasePool对象,进行释放。

apple 官方说明在以下情况下使用@autoreleasepool

  1. 如果你编写的程序不是基于 UI 框架的,比如说命令行工具;
  2. 如果你编写的循环中创建了大量的临时对象;
  3. 如果你创建了一个辅助线程。
@autoreleasepool的内部结构

我们使用clang编译一下main.m文件 cd到main.m 的目录 使用clang -rewrite-objc main.m

我们可以看到下面这样的代码,内部其实是调用了objc_autoreleasePoolPush()方法 以及objc_autoreleasePoolPop()方法

结果分析:{}的内部只有一个结构体变量,看看这个结构体,也就是一个初始化函数,析构函数,那么是不是就饿会死意味着这个局部变量的生命周期就是在这个{}的内部,意味着{}开始的时候objc_autoreleasePoolPush(),{}结束的时候objc_autoreleasePoolPop()。
那么这个结构体到底是什么,我们去runtime看看

autorelease释放的流程
  1. 我们进入到runtime object.mm 我们通过push方法找到这个类AutoreleasePoolPage

结果分析:我们编译之后调用的函数其实是AutoreleasePoolPage调用push()/pop()方法。
那么这个AutoreleasePoolPage是什么呢?其实AutoreleasePoolPage就是用来存储要管理的对象的。我们看一下这个AutoreleasePoolPage的结构体。

我们可以看到AutoreleasePoolPage就是一个双向链表。
为什么说是固定大小呢?这里面我们可以看到规定大小是1<<14也就是2的14次方。可能版本不一样,老版本中是4096个字节。

那么这个push做了什么呢?

一般情况都会走autoreleaseFast方法。那么他到底做了什么呢?

结果分析:开始的时候回去检测有没有poolPage如果有的话就压栈一个POOL_BOUNDARY ,POOL_BOUNDARY相当于每个@autorealsePool的分界线。

那么我们调用autoRealse之后,系统怎么处理呢?

我们可以看到也是通过autoreleaseFast方法将这个obj加入到page中。

那么他是怎么去释放的呢。

我们可以看到这个逻辑就是通过while循环一直去获取对象,执行realse操作。

所以总结:对象的自动释放池其实就是一个个固定大小的双向链表管理的,通过添加POOL_BOUNDARY来分隔多个@autoreleasepool的嵌套。接收到runloop的即将休眠,以及退出的通知 之后执行pop操作,通过next不断去获取obj,执行realse操作释放内存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值