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

内存管理、自动释放池

作者: 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