推广

iOS autoreleasePool原理总结

iseeyu2年前 (2024-02-21)推广128

AutoreleasePoolPage结构图.png

  • 1.AutoreleasePoolPage 本质是这么一个节点对象,大小是4096字(PAGE_MAX_SIZE:4096)。
  • 2.前7个变量都是8字节,剩下的4040字节存储着autorelease对象地址
    1. push的调用分析
void *
objc_autoreleasePoolPush(void)
{
    return AutoreleasePoolPage::push();
}

static inline void *push()
{
    return autoreleaseFast(POOL_BOUNDARY);
}

static inline id *autoreleaseFast(id obj)
{
   //hotPage()表示当前页的 AutoreleasePoolPage 节点
    AutoreleasePoolPage *page = hotPage(); 
    if (page && !page->full()) {
     // 当前 page 存在且没有满时,直接将对象添加到当前 page 中,即 next 指向的位置
        return page->add(obj); 
    } else if (page) { 
       // 当前 page 存在且已满时,创建一个新的 page ,并将对象添加到新创建的 page 中
        return autoreleaseFullPage(obj, page); 
    } else {
        // 当前 page 不存在时,即还没有 page 时,创建第一个 page ,并将对象添加到新创建的 page 中
        return autoreleaseNoPage(obj); 
    }
}
[obj autorelease], 给对象添加 autorelease 方法, 其实内部就是直接调用了 autoreleaseFast
4.autoreleasePool的结构和工作原理
  • autoreleasepool本质上就是一个指针堆栈,内部结构是由若干个以AutoreleasePoolPage对象为结点的双向链表组成,系统会在需要的时候动态地增加或删除page节点,如下图即为AutoreleasePoolPage组成的双向链表:

    截屏2021-03-05 下午4.39.46.png

  • 参考上图,整个流程大概如下:

1.在运行循环开始前,系统会自动创建一个autoreleasepool(一个autoreleasepool会存在多个AutoreleasePoolPage),此时会调用一次objc_autoreleasePoolPush函数,runtime会向当前的AutoreleasePoolPage中add进一个POOL_BOUNDARY(哨兵对象),代表autoreleasepool的起始边界地址),并返回此哨兵对象的内存地址。

2.这时候next指针则会指向POOL_BOUNDARY(哨兵对象)后面的地址(对象地址1)。

3.后面我们创建对象,如果对象调用了autorelease方法(ARC编译器会给对象自动插入autorelease),则会被添加进AutoreleasePoolPage中,位置是在next指针指向的位置,如上面next指向的是对象地址1,这是后添加的对象地址就在对象地址1这里,然后next就会 指向到对象地址2 ,以此类推,每添加一个地址就会向前移动一次,直到指向end()表示已存满。

4.当不断的创建对象时,AutoreleasePoolPage不断存储对象地址,直到存满后,则又会创建一个新的AutoreleasePoolPage,使用child指针和parent指针指向下一个和上一个page,从而形成一个双向链表,对象地址存储的顺序如图所示。

5.当调用objc_autoreleasePoolPop(哨兵对象地址)时(调用时机后面说),假设我们如上图,添加最后一个对象地址8,那么这时候就会依次由对象地址8 -> 对象地址1,每个对象都会调用release方法释放,直到遇到哨兵对象地址为止。

5.autoreleasepool的嵌套

当多个autoreleasepool嵌套,对象的释放,会是什么情况呢?
每次新建一个@ autoreleasepool,就会执行一次push操作,对应的具体实现就是往AutoreleasePoolPage中的next位置插入一个POOL_BOUNDARY(哨兵对象)。
如下:

@autoreleasepool   {//autoreleasepool1
       NSObject * obj1 = [[NSObject alloc] init];
   
    @autoreleasepool  {//autoreleasepool2
        NSObject * obj2 = [[NSObject alloc] init];
        NSObject * obj3 = [[NSObject alloc] init];
    }
}

autoreleasepool的嵌套.png

释放流程:
1.当autoreleasepool1创建时,会添加哨兵对象1,接着obj1的创建,则把obj1地址添加进来。

  1. 当autoreleasepool2创建,会添加哨兵对象2,位置是obj1后面(上面next指针指向原理),然后依次把obj2和obj3加进来。

3.当autoreleasepool2结束时,obj3,obj2,会找到离它们最近的autoreleasepool即
autoreleasepool2,然后依次调用release,直到哨兵对象2位置。

4.当autoreleasepool1结束时,当obj1调用release,直到哨兵对象1位置,

6. autorelaeasepool、NSRunLoop 、子线程三者的关系

1.主线程默认为我们开启 Runloop,Runloop 会自动帮我们创建Autoreleasepool,并进行Push、Pop 等操作来进行内存管理。

2.子线程默认不开启runloop,当产生autorelease对象时候,会将对象添加到最近一次创建的autoreleasepool中,一般是main函数中的autoreleasepool,由主线程runloop管理;也就是不用手动创建Autoreleasepool,线程销毁时在会在最近一次创建的autoreleasepool 中释放对象。

3.自定义的 NSOperation 和 NSThread 需要手动创建自动释放池。比如: 自定义的 NSOperation 类中的 main 方法里就必须添加自动释放池。否则出了作用域后,自动释放对象会因为没有自动释放池去处理它,而造成内存泄露。
但对于 blockOperation 和 invocationOperation 这种默认的Operation ,系统已经帮我们封装好了,不需要手动创建自动释放池。

4.AutoreleasePool是按线程一一对应的(结构中的thread指针指向当前线程),每开一个线程,会有与之对应的AutoreleasePool。

点个赞再走呗~

扫描二维码推送至手机访问。

版权声明:本文由西安泽虎代运营发布,如需转载请注明出处。

转载请注明出处https://0291.com.cn/post/56731.html

相关文章

SEO网站标题title中用什么标点符号好?

SEO网站标题title中用什么标点符号好?

“好的SEO网站标题标题标点符号“几乎每一个想做网站优化的站长,会遇到问题在第一个网站,也是我们必须使用标点符号怎么写网站标题和元信息?分隔的,什么样的性格独立的关键字?能做的词与词之间的关联程度,并能使搜索引擎来区分。这是一个看差异和函数符号的使用。逗号“,”注意到,一个逗号有两种,一种是中国政府...

干货分享:从0到1搭建会员体系

干货分享:从0到1搭建会员体系

编辑导读:现在几乎每一个平台都有自己的会员,甚至连进餐厅吃饭都会邀请你加入会员。有些产品的会员做的风生水起,但是有些产品的会员则无人问津。这背后的原因在哪?本文作者将分享从0到1搭建会员体系的心得体会,希望对各位有帮助。 越来越多的平台都在做会员,比如:京东plus会员、腾讯视...

如何寻找到高质量的外链平台。

如何寻找到高质量的外链平台。

虽然搜索引擎给予外链的权重越来越低了,但是外链仍然是一个站点不可或缺的的一项内容,高质量的外链总是能给站点带来相关的权重,对于提升站点排名还是有很大促进作用的。所以作为seo人员,我们还是需要去给站点增加一定量的外链,特别是高质量的外链(这包括高质量友情链接)。 那么究竟有哪些方法来寻找...

站点跳出率对优化的影响是什么。

站点跳出率对优化的影响是什么。

是多少,跳出率指的是用户通过搜索关键字访问你的网站并只看一个页面的访问量和总访问量的百分比。 对于SEO统计、相关数据分析,我们往往会误解,跳转率高会降低目标页面的排名;低的弹出率会提高目标页面的排名 因此,在实践中,这是一种片面的观点;在评价一个网站的跳出率时,不能简单地从跳出...

这样做,才能不让你的信息流广告死在落地页上!

这样做,才能不让你的信息流广告死在落地页上!

始之前,我们先聊一下: “你曾经上过多少标题党的当?” 大家可以留言,说一说你曾遇到的  “标题党”、“震惊部”  那些事! 接下来,进入到我们今天的分享的话题: “文不对题的落地页,究竟让我们的广告损失了多少潜在客户?” 一、落地页恶性循环 作为每天都和广...

淘宝自然搜索优化方法技巧是什么(淘宝搜索引擎优化)

淘宝自然搜索优化方法技巧是什么(淘宝搜索引擎优化)

搜索是一个主动词,需要买家主动输入某个关键词或者点击淘宝系统推荐的关键词,然后进入一个多宝贝展示页面,这个展示页面会有很多不同的宝贝,他们的不同会体现在产品的销量、图片、标题上。...

现在,非常期待与您的又一次邂逅

我们努力让每一部企业宣传片和抖音短视频成为商业大片