AutoreleasePool简记

本文介绍了Objective-C中的AutoreleasePool,讨论了它的作用、实现原理以及嵌套使用。AutoreleasePool通过双向链表的形式实现,用于管理内存中的对象,支持线程间的独立内存管理。在多线程环境中,每个线程都有自己的根AutoreleasePoolPage。理解AutoreleasePool对于优化iOS应用的内存使用至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

相关资料:

自动释放池的前世今生

Objective-C Autorelease Pool 的实现原理


AutoreleasePool是什么,有什么用?

自动释放池,一个无需手动释放内存的对象指针存储池


实现这样的存储池有什么要素?

可伸缩的存储空间

能获取的存储空间边界的方式

AutoreleasePool支持嵌套:所以每个存储空间内需要记忆嵌套的存储空间标志


oc实现?

这么一段存储空间,oc的实现是双向链表,链表的每个节点是等大小的堆栈,当节点堆栈存满后再创建子节点存储,每个堆栈的底部会存储等量的信息,包括空间边界即指向开始位置和结束位置的指针

加入autoreleasepool:哨兵对象(POOL_SENTINEL)入栈

加入autoreleasepool内的对象:对象入栈,栈顶指针(*next指针)移动。

移除autoreleasepool:传入需要移除的地址,计算得到地址所在的链表节点,向下找到最近的哨兵对象,移除哨兵对象后的所有元素和子节点

嵌套的autoreleasepool?

在同一线程执行过程内,假设一个父autoreleasepool嵌套两个子autoreleasepool,那么两个子autoreleasepool的执行顺序一定是先进先出,那么嵌套的autoreleasepool可直接加入链表尾部的节点堆栈中,则记忆标志就被父autoreleasepool的结束位置指针代替。即链表存储的相邻autoreleasepool是父子关系。

多线程会有各自的根AutoreleasePoolPage


代码里叫什么?

每个节点存储的基础信息为:AutoreleasePoolPage,结构如下(图片来自自动释放池的前世今生):

空间边界:POOL_SENTINEL 和 *next      (每个autoreleasepool入栈会首先加入POOL_SENTINEL标志)


链表结构(图片来自Objective-C Autorelease Pool 的实现原理):



Tips:

如果需要实际动手操作:
1.下载objc源码调试(如: 苹果官方地址,大神的github: RetVal的Github)
2.在main.m中写入autoreleasepool
3.lldb断点调试:
找到当前hotpage: expr AutoreleasePoolPage::hotPage()
AutoreleasePoolPage可以调用printAll来查看当前页堆栈内容
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值