美文网首页
AutoreleasePool什么时候释放

AutoreleasePool什么时候释放

作者: 吕建雄 | 来源:发表于2019-09-25 11:00 被阅读0次

Autorelease对象什么时候被释放?

源码地址

在没有手动添加AutoreleasePool的情况下,Auturelease对象是在当前的runloop迭代结束的时候进行释放;而它能否释放的原因是系统在每个runloop的迭代中都加入了自动释放池的push和pop。

ARC下,使用@autoreleasepool{}来使用一个AutoreleasePool,随后编译器将其修改为下面的样子:

void *context = objc_autoreleasePoolPush();

//{}中的代码

objc_autoreleasePoolPop(context)

这两个函数都是对AutoreleasePoolPage的简单封装,所以自动释放机制的核心就在与AutoreleasePoolPage这个类。

AutoreleasePool类结构

AutoreleasePool实际上是一个典型的双链表结构,每个page的大小为4096Byte;

自动释放池的工作过程:

void *objc_autoreleasePoolPush()内部实际调用的是AutoreleasePoolPage::push()函数,其实现如下:

push函数实现

hotPage()是找出当前正在使用的Page,第一次调用时hotPage为NULL,所以会新建一个parent=NULL的AutoreleasePoolPage对象作为自动释放池加入到栈中,并将其设置为hopPage,然后返回POOL_SENTINEL的地址赋值给main()函数里的变量__autoreleasepool;

然后将一个哨兵对象POOL_SENTINEL压入栈顶,即调用,即调用autoreleaseFast(POOL_SENTINEL)

autoreleaseFast函数

添加对象进入到自动释放池

可以看出,当前有page并且没有满,则直接将对象入栈顶(page->add(obj))

add函数

将对象压入栈顶,然后将栈顶指针下移;

如果当前page已满,则调用autoreleaseShow

autoreleaseShow函数

基本逻辑:如果page不存在则,创建新的自动释放池(PoolPage),并将对象加进池子;如果已经存在自动释放池在栈中,且hotPage满了,则遍历其子page,如果存在没满(page->full()==NO)的子page,则将该子page设置为hotPage,否则如果都满了,则以最后一个子page为父page,新建一个page,插入当前的page链表,同样设置该新建的page为hotPage,然后将自动释放对象加入page;

销毁自动释放池

void AutoreleasePoolPage::pop(void *token)

此处的token参数,即push()的返回值,实际上就是POOL_SENTINEL的地址;通过该地址即可找到所在Page的地址指针

pop函数

该过程主要分为两步:

1,page->releaseUntil(stop); //对自动释放池中对象调用objc_release()进行释放,对栈顶到POOL_SENTINEL之间的所有对象调用objc_release(),进行引用计数减1;

2,page->kill(); //清空page对象

注意函数中的注释:

// memory: delete empty children

// hysteresis: keep one empty child if this page is more than half full

// special case: delete everything for pop(0)

保持一个空的子page当当前page大于一半时(可能是为了马上要新建page节省开销)

当调用pop(0)时,会清理掉所有的page; 

if (page->child) {

          if (page->lessThanHalfFull()) {

              page->child->kill(); //如果当前存放的对象少于一半全部删除

          }

          else if (page->child->child) {

              page->child->child->kill();//存放对象多余一半,则保留一个子page,节省开销

          }

      }

相关文章

网友评论

      本文标题:AutoreleasePool什么时候释放

      本文链接:https://www.haomeiwen.com/subject/cdbmuctx.html