Aurorelease机制

来源:互联网 发布:java中indexof的用法 编辑:程序博客网 时间:2024/06/06 10:50

在我接触到的编程项目中。基本上大部分程序都是从main文件中的main方法开始执行的。

而在iOS开发中也有一个Main文件。与一般的Main文件不同的是这个文件包含有一段代码

int main(int argc, char * argv[]) {    @autoreleasepool {        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));    }}
这段代码特殊的地方在于@autoreleasepool代码块下包含的一个方法

那么这个@autoreleasepool{}有什么用呢

简单的来说这段代码可以使得在其代码块内的对象release一次。但是这个答案明显不能让作为程序员的我们的好奇心得到满足

那么我们就来仔细分析一下这其中的原理

Autorelease对象

我们知道在不管MRC时期还是ARC时期。Autorelease机制都是对内存管理的一大助力。在MRC中,调用[objc autorelease]来延迟对象释放是一件简单正常的事情。而在ARC中。我们甚至完全不用知道Autorelease就能管理好内存。而在这背后,编译器帮我们做了什么。他们之间是如何协作管理的呢。让我们一起了解
在ARC中,上述代码在编译器的处理下会变成
void *context = objc_autoreleasePoolPush();//代码块内容objc_autoreleasePoolPop()

这两个函数都是对AutoreleasePoolPage的简单封装。所以自动释放机制的核心就是AutoreleasePoolPage这个用C++写成的对象


从给出的参数我们可以得到以下信息

1.autoreleasePoolPage没有自己的结构。是一个由若干个相同对象组成的双向链表.

2.每个AutoreleasePoolPage都有一个对应的线程。见参数pthread_t const thread.

3.每个AutoreleasePoolPage对象都会开辟一个4096字节的虚拟内存。除了上图出现的实例变量所占的空间其余都是给autorelease对象占用

4.next指向的是下一个Autorelease对象进来的虚拟内存空间地址。

5.当一个AutoreleasePoolPage满了就会开辟一个新的AutoreleasePoolPage。连接链表。新加入的autorelease对象将加入到下一个Page中去

如下图所示是一个即将满了的autoreleasePoolPage对象


每次给对象发送autorelease消息就讲对象的地址加入到next指针所在位置。当本页虚拟内存满了后开辟一个新A的AutoreleasePoolPage对象,next指针将指向新的栈底(begin)位置所在。

以上就是Autorelease加入操作

释放操作的话如下图所示

每次push进一个对象就会生成一个哨兵对象。objc_autoreleasePoolPage()返回的就是这个哨兵对象的地址。

释放的时候以哨兵对象地址为标准。从最新的page一直往前释放。即给每个对象发送-release消息。直至哨兵对象。


这就是最终释放后的样子





原创粉丝点击