autoreleasepool问题汇总

AutoreleasepoolPage

调用autorelease对象最终都是通过AutoreleasepoolPage对象来管理的。AutoreleasepoolPage对象的结构如下

Next:指向最新添加的autorelease对象的下一个位置,也就是第一个可以用的位置。

thread:当前的线程。

parent:指向父节点,第一个节点的parent是nil。

Child:指向子节点,最后一个节点的child指向nil。

Depth:表示深度。

magic:用来校验AutoreleasepoolPage结构是否完整。

Hiwat:数据容器的上限

 

每个autoreleasepoolpage对象占用4096字节内存,除了存放内部的成员变量,剩下的存放autorelease对象的地址。autoreleasepoolpage对象是通过双向链表的形式连接在一起的。

push和pop方法

当对象调用[object autorelease]函数时候就会将对象加入到autoreleasepool中,也就是会进行push操作。

push操作,会调用到autoreleaseFast函数。这就是它的初始化函数。通过调用hotpage()函数,判断有三种情况:

1、如果hotpage存在,而且容量没满,那么直接调用add函数添加对象。

2、如果hotpage存在,但是已经满了,调用autoreleaseFullPage函数,并初始化一个AutoreleasePage标记为hotpage。

3、如果hotpage不存在,调用autoreleaseNoPage函数,创建一个AutoreleasePage标记为hotpage,添加哨兵对象。

 

Autoreleasepool的pop操作主要是

1、通过哨兵对象获取到所在的autoreleasepoolpage

2、调用page->releaseUntil(stop)函数,对栈顶到stop对象都调用objc_release()操作引用计数-1

3、最后调用child的kill方法。

 

autoreleasepool的创建和释放时机

创建

App启动后,主线程的runloop里会添加两个observer,第一个是监视loop的entry事件,在回调事件内调用了autoreleaspoolpush创建自动释放池。并设置了这个observer的order优先级最高(负的2的32次方-1),保证创建自动释放池在其他回调之前。

释放

第二个observer监视的是准备休眠和即将退出runloop,其内调用了autoreleasepoolpop释放自动释放池,其observer的order设置优先级最低(2的32次方-1),保证了自动释放池的释放在其他回调之后。防止了自动释放池过早的释放对象导致崩溃。

 

对象释放时机

mrc下

手动调用autorelease方法,并不是根据对象的作用域来决定释放时机的,而是根据的runloop的不同状态,当runloop结束时系统才会清理掉autorelease处理的对象。而runloop结束并没有固定的duration。

arc下

局部对象是在出了作用域后就销毁,系统在它出作用域的时候,自动调用其release方法。

 

autoreleasepool使用场景

官方文档说明使用场景有三种:

1、写命令行程序时,没有UI框架的程序。因为autorelease机制是基于UI framework,因此如果不是基于UI framework的程序需要自己管理对象的生命周期。

2、写循环,里边包含了大量的临时创建的对象。因为autorelease触发时机是在下一次的runloop的时候,因此如果在循环内有大量的autorelease对象,那么在下一次的runloop回来之前没有机会被释放掉,会导致内存爆增,可能导致崩溃问题。

3、自己创建了线程。

 

什么对象会加入到Autoreleasepool中

1、使用alloc、copy、new等方法进行初始化时,系统管理对象内存。

2、使用__weak修饰的对象,为了保证引用不被废弃,会注册到Autoreleasepool中。

3、id的指针或者对象的指针,在没有显示指定时会被注册到Autoreleasepool中。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值