AutoreleasePool 重新梳理

作者: 雨三楼 | 来源:发表于2019-08-26 16:56 被阅读0次

AutoreleasePool 是一个抽象概念,并没有实际结构,真实的结构是一个双向链表『AutoreleasePoolPage』,由C++实现。

1.数据结构

其数据结构如下:

class AutoreleasePoolPage 
{

#define POOL_SENTINEL nil
    static pthread_key_t const key = AUTORELEASE_POOL_KEY;
    static uint8_t const SCRIBBLE = 0xA3;  // 0xA3A3A3A3 after releasing
    static size_t const SIZE = 
#if PROTECT_AUTORELEASEPOOL
        PAGE_MAX_SIZE;  // must be multiple of vm page size
#else
        PAGE_MAX_SIZE;  // size and alignment, power of 2
#endif
    static size_t const COUNT = SIZE / sizeof(id);

    magic_t const magic;
    id *next;
    pthread_t const thread;
    AutoreleasePoolPage * const parent;
    AutoreleasePoolPage *child;
    uint32_t const depth;
    uint32_t hiwat;
}

成员变量说明:

next:游标,一直指向最新入栈的autorelease对象的下一个位置。

key:TLS技术,既Thread Local Storage(TLS)线程局部存储。目的很简单,将一块内存作为某个线程专有的存储,以key-value的形式进行读写。AutoreleasePoolPage将这块区域用作存储最新的Page,既hotPage。

SIZE:单个page的最大存储数量,AutoreleasePoolPage以双向链表的形式存在,但是单个page的存储是有限额的,(id *) ((uint8_t *)this+SIZE)

thread:当前线程pthread_self()

2.push和pop

当我们手动调用@autoreleasePool的时候,编译器会自动将大括号内的所有对象标记为autorelease前缀。AutoreleasePoolPage::autorelease((id)this)当前对象本身作为参数入参,不过在讨论对象的autorelease之前,编译器还插入了两个方法:

void *pool = objc_autoreleasePoolPush();
……
……
……
objc_autoreleasePoolPop(pool);

前者做了和对象的autorelease相同的事情:

static inline id *autoreleaseFast(id obj)
    {
        AutoreleasePoolPage *page = hotPage();
        if (page && !page->full()) {
            return page->add(obj);
        } else if (page) {
            return autoreleaseFullPage(obj, page);
        } else {
            return autoreleaseNoPage(obj);
        }
    }
id *add(id obj)
    {
        assert(!full());
        unprotect();
        id *ret = next;  // faster than `return next-1` because of aliasing
        *next++ = obj;
        protect();
        return ret;
    }

主要就是移动游标,并且返回当前位置,这个返回参数的意义主要体现在

objc_autoreleasePoolPop(pool);的入参中,pool记录着一个pool的初始位置,根据这个位置和当前的hotPage位置,遍历中间所有的对象,进行释放。并且由于双向链表的结构,很容易跨page进行遍历。

相关文章

  • AutoreleasePool 重新梳理

    AutoreleasePool 是一个抽象概念,并没有实际结构,真实的结构是一个双向链表『AutoreleaseP...

  • runtime

    autoreleasePool autoreleasePool认识 autoreleasePool怎么加进去的,什...

  • 重新梳理生活~

    你不在家~ 空落落的~ 安静下来~ 重新梳理生活~ 认真吃饭~ 坚持读书~ 坚持瑜伽~ 坚持画画~ 时间富裕~ 我...

  • 梳理,重新启程

    已经一周没有写日记了,不是不想写,但真的是没有心情写。 每个部门的招聘都告急,心理咨询师考试复习还差一大截,自己建...

  • 重新梳理自己

    一、系统层面(world/who else) 以前我的世界是充满未知的,是非黑即白的,是充满艰难的;世界不是恒久不...

  • 重新梳理认知

    明确分工,每个人需要对负责的模块有担当。 要有计划,对应的做事的周期和开发节奏。 要有反馈,将遇到的问题抛出来,避...

  • iOS autoreleasepool 原理

    iOS autoreleasepool 原理 arr 是再什么时机释放? @AutoreleasePool{代码}...

  • iOS-底层原理 :内存管理(二)AutoReleasePool

    本文主要分析 AutoReleasePool 以及 NSRunLoop 的底层实现 AutoReleasePool...

  • iOS内存管理(三)AutoReleasePool & NSRu

    本文主要分析 AutoReleasePool 以及NSRunLoop的底层实现 AutoReleasePool 自...

  • autoreleasePool、线程、RunLoop

    内存规则理解 Thread与autoReleasePool thread创建需要创建autoreleasePool...

网友评论

    本文标题:AutoreleasePool 重新梳理

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