zoukankan      html  css  js  c++  java
  • iOS进阶四-自动释放池原理

    概述

    AutoreleasePool(自动释放池)是OC中的一种内存自动回收机制,它可以延迟加入AutoreleasePool中的变量release的时机。在正常情况下,创建的变量会在超出其作用域的时候release,但是如果将变量加入AutoreleasePool,那么release将延迟执行。

    @autoreleasepool实现本质

    在终端中使用clang -rewrite-objc命令将OC代码重写成C++的实现

     

     __AtAutoreleasePool是C++定义类

     

     @autoreleasepool最终实现如下

     AutoreleasePoolPage

    自动释放池的主要底层数据结构是:__AtAutoreleasePool 和 AutoreleasePoolPage

    调用了autorelease的对象最终由AutoreleasePoolPage对象来管理

     objc4源码:NSObject.mm

     

    每一个AutoreleasePoolPage对象占用4094字节内存,本身成员占用56字节,剩下的空间用来存放autorelease对象的地址

    所有的AutoreleasePoolPage对象通过双向链表的形式连接在一起

    AutoreleasePoolPage管理autorelease的的对象过程 

    @autoreleasepool {}就对应 objc_autoreleasePoolPush(); 和  objc_autoreleasePoolPop(atautoreleasepoolobj);

    objc_autoreleasePoolPush(); 内部实现:往当前hot AutoreleasePoolPage 添加 POOL_BOUNDARY,返回POOL_BOUNDARY所在的内存地址

    @autoreleasepool {}代码快如果存在对象调用了autorelease,就会将对象内存地址保存至AutoreleasePoolPage 

    objc4 NSObject.mm 对象- (id)autorelease方法实现

     

    添加POOL_BOUNDARY和AutoreleasePoolPage对象后如下图 

    每执行@autoreleasepool底层对应执行objc_autoreleasePoolPush(); 就会往AutoreleasePoolPage添加POOL_BOUNDARY,并返回POOL_BOUNDARY所在AutoreleasePoolPage的内存空间地址

    @autoreleasepool{}大括号结束 内部创建的__AtAutoreleasePool对象销毁,调用析构函数objc_autoreleasePoolPop(atautoreleasepoolobj);

    AutoreleasePoolPage开始从后往前遍历autorelease对象调用release方法直到objc_autoreleasePoolPop()传入的POOL_BOUNDARY地址为止

     查看AutoreleasePoolPage结构

    Foundation内部存在一个全局的函数 声明引用 然后在调用

    控制台输出

     

     RunLoop与autorelease

    iOS程序运行 在主线程中注册了2个Observer 分别监听RunLoop的 kCFRunLoopEntry  kCFRunLoopBeforeWaiting 两个状态(通过打印主线程的RunLoop)

    第一个Observer监听了kCFRunLoopEntry 会调用objc_autoreleasePoolPush

    第二个Observer监听了kCFRunLoopBeforeWaiting 会调用objc_autoreleasePoolPop

     MRC环境 调用的autorelease对象销毁时机

    iOS程序在程序入口main函数执行@autoreleasepool也就是atautoreleasepoolobj = objc_autoreleasePoolPush();操作  保证在程序中对象可以直接调用autorelease 

    上图中person对象是有RunLoop来控制的,它可能是在某次RunLoop循环中,RunLoop休眠之前调用了release 

    ARC环境 方法中创建局部对象销毁时机 

    上图中person对象取决于ARC是对person添加释放代码是生成autorelease还是在方法结束之前生成release,经过调试验证ARC在方法结束前插入一句

    [person release],所以ARC下局部对象是在方法结束释放

  • 相关阅读:
    N天学习一个linux命令之lsof
    N天学习一个linux命令之ps
    N天学习一个linux命令之yum
    N天学习一个linux命令之rsync
    N天学习一个linux命令之ss
    N天学习一个linux命令之netstat
    N天学习一个linux命令之vmstat
    N天学习一个linux命令之sort
    N天学习一个linux命令之rpm
    跨域问题
  • 原文地址:https://www.cnblogs.com/CoderHong/p/10889007.html
Copyright © 2011-2022 走看看