美文网首页
内存管理、自动释放池

内存管理、自动释放池

作者: Queen_BJ | 来源:发表于2020-09-09 18:14 被阅读0次
    内存布局
    • 栈(stack):方法调用,局部变量,是连续的,高地址向低地址扩展
    • 堆(heap):通过alloc等分配的对象,是离散的,低地址向高地址扩展,需要手动管理
    • 未初始化数据(bss):未初始化的全局变量等
    • 已初始化数据(data):已初始化的全局变量等
    • 代码段(text):程序代码

    问题一 :Autoreleasepool是实现机制是什么?它是什么时候释放内部的对象的?它内部的数据结构是什么样的?当我提到哨兵对象时,会继续问哨兵对象的作用是什么,为什么要设计它?

    编译器会将 @autoreleasepool {} 改写为:

    void * ctx = objc_autoreleasePoolPush;
        {}
    objc_autoreleasePoolPop(ctx);
    
    • objc_autoreleasePoolPush:
      把当前next位置置为nil,即哨兵对象,然后next指针指向下一个可入栈位置,AutoreleasePool的多层嵌套,即每次objc_autoreleasePoolPush,实际上是不断地向栈中插入哨兵对象。
    • objc_autoreleasePoolPop:
      根据传入的哨兵对象找到对应位置。
      给上次push操作之后添加的对象依次发送release消息。回退next指针到正确的位置。

    Autoreleasepool的原理是一个双向列表,它会对加入其中的对象实现延迟释放。
    当Autoreleasepool调用drain方法时会释放内部标记为autorelease的对象

    Autoreleasepool数据结构
    class AutoreleasePoolPage {
        magic_t const magic;
        id *next;
        pthread_t const thread;
        AutoreleasePoolPage * const parent;
        AutoreleasePoolPage *child;
        uint32_t const depth;
        uint32_t hiwat;
    };
    

    哨兵对象类似一个指针,指向自动释放池的栈顶位置,它的作用就是用于标记当前自动释放池需要释放内部对象时,释放到那个地方结束,每次入栈时它用于确定添加的位置,然后再次移动到栈顶。

    Autoreleasepool详细内容 容易理解

    Autoreleasepool底层原理

    问题二 :哪些对象会放入到Autoreleasepool中?
    有两种情况生成的对象会加入到autoreleasepool中:

    • 非alloc/new/copy/mutablecopy 开始的方式初始化时
    • id的指针或对象的指针在没有显示指定时

    相关文章

      网友评论

          本文标题:内存管理、自动释放池

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