iOS-内存管理分析(下)

前言

iOS-内存管理分析(上)以及iOS-内存管理分析(中)分析了内存的分区,布局,散列表,弱引用计数表等相关知识,这篇文章继续分析内存管理。

1 自动释放池初探

在我们的demo工程的main文件代码如下

#import 

int main(int argc, const char * argv[]) {
 
    @autoreleasepool {
        NSLog(@"Hello, World!");
    }
    return 0;
}

我们通过clang命令,看下底层,我们在main.cpp找到如下代码

int main(int argc, const char * argv[]) {

    /*  */ { __AtAutoreleasePool __autoreleasepool; 
        NSLog((NSString *)&__NSConstantStringImpl__var_folders_r7_rnm6hs1x2jg8bqy7sjwsskx00000gn_T_main_1cecfd_mi_0);
    }
    return 0;
}

@autoreleasepool被注释了,替换的是*__AtAutoreleasePool __autoreleasepool; *这个。
__AtAutoreleasePool是一个结构体,如下

struct __AtAutoreleasePool {
  __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}
  ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}
  void * atautoreleasepoolobj;
};

这里有一个构造和析构函数,构造函数创建一个objc_autoreleasePoolPush对象,释构函数调用objc_autoreleasePoolPop释入这个objc_autoreleasePoolPush对象。
当然我们还可以通过汇编分析流程,这里不再叙述。

2 自动释放池结构

objc_autoreleasePoolPushobjc_autoreleasePoolPop的底层到底是什么,做了什么操作,我们接下来分析下。
我们在objc(818)的源码中搜索下objc_autoreleasePoolPush这个函数,找到如下代码

void *
objc_autoreleasePoolPush(void)
{
    return AutoreleasePoolPage::push();
}

调用了AutoreleasePoolPage它的push()函数,我们进去看下,如下

class AutoreleasePoolPage : private AutoreleasePoolPageData

AutoreleasePoolPage继承于AutoreleasePoolPageData

 Autorelease pool implementation

   A thread's autorelease pool is a stack of pointers.
   Each pointer is either an object to release, or POOL_BOUNDARY which is 
     an autorelease pool boundary.
   A pool token is a pointer to the POOL_BOUNDARY for that pool. When 
     the pool is popped, every object hotter than the sentinel is released.
   The stack is divided into a doubly-linked list of pages. Pages are added
     and deleted as necessary. 
   Thread-local storage points to the hot page, where newly autoreleased 
     objects are stored. 

自动释放池与线程有关联的。POOL_BOUNDARY就是哨兵对象边(自动释放池边界),不能无限制出栈,如果没有这个边界,不断的出栈,会出现访问野指针。
这里说了自动释放池是一个双向链表。
我们再来看下AutoreleasePoolPageData

struct AutoreleasePoolPageData
{
#if SUPPORT_AUTORELEASEPOOL_DEDUP_PTRS
    struct AutoreleasePoolEntry {
        uintptr_t ptr: 48;
        uintptr_t count: 16;

        static const uintptr_t maxCount = 65535; // 2^16 - 1
    };
    static_assert((AutoreleasePoolEntry){ .ptr = MACH_VM_MAX_ADDRESS }.ptr == MACH_VM_MAX_ADDRESS, "MACH_VM_MAX_ADDRESS doesn't fit into AutoreleasePoolEntry::ptr!");
#endif

    magic_t const magic; // 16
    __unsafe_unretained id *next; // 8
    pthread_t const thread; // 8
    AutoreleasePoolPage * const parent; // 8
    AutoreleasePoolPage *child; // 8
    uint32_t const depth; // 4
    uint32_t hiwat;  // 4
AutoreleasePoolPageData(__unsafe_unretained id* _next, pthread_t _thread, AutoreleasePoolPage* _parent, uint32_t _depth, uint32_t _hiwat)
        : magic(), next(_next), thread(_thread),
          parent(_parent), child(nil),
          depth(_depth), hiwat(_hiwat)
    {
    }
};
  • magic⽤来校验AutoreleasePoolPage的结构是否完整;
  • next指向最新添加的autoreleased对象的下⼀个位置,初始化时指向begin();
  • thread指向当前线程;
  • parent指向⽗结点,第⼀个结点的parent值为nil;
  • child指向⼦结点,最后⼀个结点的child值为nil;
  • depth代表深度,从0开始,往后递增1;
  • hiwat代表highwatermark最⼤⼊栈数量标记

我们改下main.m源码,压栈一个对象,

#import 
extern void _objc_autoreleasePoolPrint(void);

int main(int argc, const char * argv[]) {
    @autoreleasepool {
       
        NSObject *objc = [[[NSObject alloc] init] autorelease];
        _objc_autoreleasePoolPrint();

    }
    return 0;
}

这里一定要把arc关掉。
运行项目,如下

objc[27889]: AUTORELEASE POOLS for thread 0x1000ebe00
objc[27889]: 2 releases pending.
objc[27889]: [0x10200c000]  ................  PAGE  (hot) (cold)
objc[27889]: [0x10200c038]  ################  POOL 0x10200c038
objc[27889]: [0x10200c040]       0x10060dfc0  NSObject
objc[27889]: ##############
Program ended with exit code: 0

这里可以看到NSObject对象是压入栈了。
这里有两个对象的原因,是因为哨兵对象也是一个对象。

3 自动释放池的创建和压栈

自动释放池的创建和压栈是如何进行的,我们分析它的源码看下。
我们看下AutoreleasePoolPage::push();的源码,如下

 static inline void *push() 
    {
        id *dest;
        if (slowpath(DebugPoolAllocation)) {
            // Each autorelease pool starts on a new pool page.
            dest = autoreleaseNewPage(POOL_BOUNDARY);
        } else {
            dest = autoreleaseFast(POOL_BOUNDARY);
        }
        ASSERT(dest == EMPTY_POOL_PLACEHOLDER || *dest == POOL_BOUNDARY);
        return dest;
    }

我们再来看下autoreleaseFast这个函数,源码如下

 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);
        }
    }

这里判断页面是否存在并且没有满,直接add进去。
如果满了调用autoreleaseFullPage处理,如果没有这个页面,调用autoreleaseNoPage创建。
我们再来看下autoreleaseNoPage,如下

 static __attribute__((noinline))
    id *autoreleaseNoPage(id obj)
    {
        // "No page" could mean no pool has been pushed
        // or an empty placeholder pool has been pushed and has no contents yet
        ASSERT(!hotPage());

        bool pushExtraBoundary = false;
        if (haveEmptyPoolPlaceholder()) {
            // We are pushing a second pool over the empty placeholder pool
            // or pushing the first object into the empty placeholder pool.
            // Before doing that, push a pool boundary on behalf of the pool 
            // that is currently represented by the empty placeholder.
            pushExtraBoundary = true;
        }
        else if (obj != POOL_BOUNDARY  &&  DebugMissingPools) {
            // We are pushing an object with no pool in place, 
            // and no-pool debugging was requested by environment.
            _objc_inform("MISSING POOLS: (%p) Object %p of class %s "
                         "autoreleased with no pool in place - "
                         "just leaking - break on "
                         "objc_autoreleaseNoPool() to debug", 
                         objc_thread_self(), (void*)obj, object_getClassName(obj));
            objc_autoreleaseNoPool(obj);
            return nil;
        }
        else if (obj == POOL_BOUNDARY  &&  !DebugPoolAllocation) {
            // We are pushing a pool with no pool in place,
            // and alloc-per-pool debugging was not requested.
            // Install and return the empty pool placeholder.
            return setEmptyPoolPlaceholder();
        }

        // We are pushing an object or a non-placeholder'd pool.

        // Install the first page.
        AutoreleasePoolPage *page = new AutoreleasePoolPage(nil);
        setHotPage(page);
        
        // Push a boundary on behalf of the previously-placeholder'd pool.
        if (pushExtraBoundary) {
            page->add(POOL_BOUNDARY);
        }
        
        // Push the requested object or pool.
        return page->add(obj);
    }

在这里

 AutoreleasePoolPage *page = new AutoreleasePoolPage(nil);
 setHotPage(page);

创建新页面,并设置成hot页面,之后再add对象
我们再看下AutoreleasePoolPage

AutoreleasePoolPage(AutoreleasePoolPage *newParent) :
        AutoreleasePoolPageData(begin(),
                                objc_thread_self(),
                                newParent,
                                newParent ? 1+newParent->depth : 0,
                                newParent ? newParent->hiwat : 0)
    {
        if (objc::PageCountWarning != -1) {
            checkTooMuchAutorelease();
        }

        if (parent) {
            parent->check();
            ASSERT(!parent->child);
            parent->unprotect();
            parent->child = this;
            parent->protect();
        }
        protect();
    }

这里设置双向链表的数据。
我们看下的begin如下

  id * begin() {
        return (id *) ((uint8_t *)this+sizeof(*this));
    }

sizeof(*this)这时56的大小,来源于autorealeaPoolDat成员变量

    magic_t const magic;//16
    __unsafe_unretained id *next;//8
    pthread_t const thread; //8
    AutoreleasePoolPage * const parent; //8
    AutoreleasePoolPage *child; //8
    uint32_t const depth;//4
    uint32_t hiwat;//4 

magic_t是结构体,有一个uint32_4 m[4]占用16字节。
objc_thread_self(),获取当前线程。

自动释放池的成员变量也是占用空间的。

POOL 0x10080c038上方的这个是我们的哨兵对象。

4 自动释放池的满页临界和压栈出栈

当我们的页面满的时候,是如何处理的,结构又有什么变化呢,我们继续分析下源码才能得到。

我们知道内存是分页的加载的,为什么这么做呢?
假如不分页的话会出现以下情况

  • 不断的压栈出栈,会对这张表操作非常频繁,也就是说对内存操作频繁
  • 压栈出栈的时候,会对整张表进行加锁解锁,非常消耗性能
  • 所有的对象存在这张表,非常复杂,管理复杂
  • 如果某个局部发生问题,整张表都会影响
    而分页的方式就不会有这些问题
    内存分页的好处
  • 内存可以不连续
  • 性能大大的提高

我们一张表可以存放多少内存, 我们探索一下。
我们在改下我们的main.m文件

#import 
extern void _objc_autoreleasePoolPrint(void);

int main(int argc, const char * argv[]) {
    @autoreleasepool {
       
        for (int i = 0; i<4; i++) {
            NSObject *objc = [[[NSObject alloc] init] autorelease];
        }
        _objc_autoreleasePoolPrint();

    }
    return 0;
}

我们运行项目,看下效果,如下所示

objc[29930]: AUTORELEASE POOLS for thread 0x1000ebe00
objc[29930]: 5 releases pending.
objc[29930]: [0x101009000]  ................  PAGE  (hot) (cold)
objc[29930]: [0x101009038]  ################  POOL 0x101009038
objc[29930]: [0x101009040]       0x101a4b020  NSObject
objc[29930]: [0x101009048]       0x101a3f2d0  NSObject
objc[29930]: [0x101009050]       0x101a3ebf0  NSObject
objc[29930]: [0x101009058]       0x101a3dac0  NSObject
objc[29930]: ##############
KCObjcBuild was compiled with optimization - stepping may behave oddly; variables may not be available.

我们可以看到没有产生分页的效果,我们再把循环改下505,再看下效果

objc[29984]: AUTORELEASE POOLS for thread 0x1000ebe00
objc[29984]: 506 releases pending.
objc[29984]: [0x10480d000]  ................  PAGE (full)  (cold)
objc[29984]: [0x10480d038]  ################  POOL 0x10480d038
objc[29984]: [0x10480d040]       0x10132a9f0  NSObject
objc[29984]: [0x10480d048]       0x101328f20  NSObject
objc[29984]: [0x10480d050]       0x101328b70  NSObject
objc[29984]: [0x10480d058]       0x101328bd0  NSObject
objc[29984]: [0x10480d060]       0x101327b10  NSObject
objc[29984]: [0x10480d068]       0x101327b50  NSObject
objc[29984]: [0x10480d070]       0x101327100  NSObject
objc[29984]: [0x10480d078]       0x101325fd0  NSObject
objc[29984]: [0x10480d080]       0x101326010  NSObject
objc[29984]: [0x10480d088]       0x101326040  NSObject
objc[29984]: [0x10480d090]       0x101325ae0  NSObject
objc[29984]: [0x10480d098]       0x101324fc0  NSObject
objc[29984]: [0x10480d0a0]       0x1013249a0  NSObject
objc[29984]: [0x10480d0a8]       0x101324500  NSObject
objc[29984]: [0x10480d0b0]       0x101323ff0  NSObject
objc[29984]: [0x10480d0b8]       0x101323290  NSObject
objc[29984]: [0x10480d0c0]       0x101322d90  NSObject
objc[29984]: [0x10480d0c8]       0x101322630  NSObject
objc[29984]: [0x10480d0d0]       0x101322660  NSObject
objc[29984]: [0x10480d0d8]       0x10130f190  NSObject
objc[29984]: [0x10480d0e0]       0x10130f1c0  NSObject
objc[29984]: [0x10480d0e8]       0x10130e510  NSObject
objc[29984]: [0x10480d0f0]       0x10130e7d0  NSObject
objc[29984]: [0x10480d0f8]       0x10130d7b0  NSObject
objc[29984]: [0x10480d100]       0x10130d080  NSObject
objc[29984]: [0x10480d108]       0x10130d140  NSObject
objc[29984]: [0x10480d110]       0x10130be70  NSObject
objc[29984]: [0x10480d118]       0x10130ade0  NSObject
objc[29984]: [0x10480d120]       0x10130a1b0  NSObject
objc[29984]: [0x10480d128]       0x101305530  NSObject
objc[29984]: [0x10480d130]       0x101308ca0  NSObject
objc[29984]: [0x10480d138]       0x101308e60  NSObject
objc[29984]: [0x10480d140]       0x101304900  NSObject
objc[29984]: [0x10480d148]       0x1013387a0  NSObject
objc[29984]: [0x10480d150]       0x1013387b0  NSObject
objc[29984]: [0x10480d158]       0x1013387c0  NSObject
objc[29984]: [0x10480d160]       0x1013387d0  NSObject
objc[29984]: [0x10480d168]       0x1013387e0  NSObject
objc[29984]: [0x10480d170]       0x1013387f0  NSObject
objc[29984]: [0x10480d178]       0x101338800  NSObject
objc[29984]: [0x10480d180]       0x101338810  NSObject
objc[29984]: [0x10480d188]       0x101338820  NSObject
objc[29984]: [0x10480d190]       0x101338830  NSObject
objc[29984]: [0x10480d198]       0x101338840  NSObject
objc[29984]: [0x10480d1a0]       0x101338850  NSObject
objc[29984]: [0x10480d1a8]       0x101338860  NSObject
objc[29984]: [0x10480d1b0]       0x101338870  NSObject
objc[29984]: [0x10480d1b8]       0x101338880  NSObject
objc[29984]: [0x10480d1c0]       0x101338890  NSObject
objc[29984]: [0x10480d1c8]       0x101338bb0  NSObject
objc[29984]: [0x10480d1d0]       0x101338bc0  NSObject
objc[29984]: [0x10480d1d8]       0x101338bd0  NSObject
objc[29984]: [0x10480d1e0]       0x101338be0  NSObject
objc[29984]: [0x10480d1e8]       0x101338bf0  NSObject
objc[29984]: [0x10480d1f0]       0x101338c00  NSObject
objc[29984]: [0x10480d1f8]       0x101338c10  NSObject
objc[29984]: [0x10480d200]       0x101338c20  NSObject
objc[29984]: [0x10480d208]       0x101338c30  NSObject
objc[29984]: [0x10480d210]       0x101338c40  NSObject
objc[29984]: [0x10480d218]       0x101338c50  NSObject
objc[29984]: [0x10480d220]       0x101338c60  NSObject
objc[29984]: [0x10480d228]       0x101338c70  NSObject
objc[29984]: [0x10480d230]       0x101338c80  NSObject
objc[29984]: [0x10480d238]       0x101338c90  NSObject
objc[29984]: [0x10480d240]       0x101338ca0  NSObject
objc[29984]: [0x10480d248]       0x101338cb0  NSObject
objc[29984]: [0x10480d250]       0x101338cc0  NSObject
objc[29984]: [0x10480d258]       0x101338cd0  NSObject
objc[29984]: [0x10480d260]       0x101338ce0  NSObject
objc[29984]: [0x10480d268]       0x101338cf0  NSObject
objc[29984]: [0x10480d270]       0x101338d00  NSObject
objc[29984]: [0x10480d278]       0x101338d10  NSObject
objc[29984]: [0x10480d280]       0x101338d20  NSObject
objc[29984]: [0x10480d288]       0x101338d30  NSObject
objc[29984]: [0x10480d290]       0x101338d40  NSObject
objc[29984]: [0x10480d298]       0x101338d50  NSObject
objc[29984]: [0x10480d2a0]       0x101338d60  NSObject
objc[29984]: [0x10480d2a8]       0x101338d70  NSObject
objc[29984]: [0x10480d2b0]       0x101338d80  NSObject
objc[29984]: [0x10480d2b8]       0x101338d90  NSObject
objc[29984]: [0x10480d2c0]       0x101338da0  NSObject
objc[29984]: [0x10480d2c8]       0x101338db0  NSObject
objc[29984]: [0x10480d2d0]       0x101338dc0  NSObject
objc[29984]: [0x10480d2d8]       0x101338dd0  NSObject
objc[29984]: [0x10480d2e0]       0x101338de0  NSObject
objc[29984]: [0x10480d2e8]       0x101338df0  NSObject
objc[29984]: [0x10480d2f0]       0x101338e00  NSObject
objc[29984]: [0x10480d2f8]       0x101338e10  NSObject
objc[29984]: [0x10480d300]       0x101338e20  NSObject
objc[29984]: [0x10480d308]       0x101338e30  NSObject
objc[29984]: [0x10480d310]       0x101338e40  NSObject
objc[29984]: [0x10480d318]       0x101338e50  NSObject
objc[29984]: [0x10480d320]       0x101338e60  NSObject
objc[29984]: [0x10480d328]       0x101338e70  NSObject
objc[29984]: [0x10480d330]       0x101338e80  NSObject
objc[29984]: [0x10480d338]       0x101338e90  NSObject
objc[29984]: [0x10480d340]       0x101338ea0  NSObject
objc[29984]: [0x10480d348]       0x101338eb0  NSObject
objc[29984]: [0x10480d350]       0x101338ec0  NSObject
objc[29984]: [0x10480d358]       0x101338ed0  NSObject
objc[29984]: [0x10480d360]       0x101338ee0  NSObject
objc[29984]: [0x10480d368]       0x101338ef0  NSObject
objc[29984]: [0x10480d370]       0x101338f00  NSObject
objc[29984]: [0x10480d378]       0x101338f10  NSObject
objc[29984]: [0x10480d380]       0x101338f20  NSObject
objc[29984]: [0x10480d388]       0x101338f30  NSObject
objc[29984]: [0x10480d390]       0x101338f40  NSObject
objc[29984]: [0x10480d398]       0x101338f50  NSObject
objc[29984]: [0x10480d3a0]       0x101338f60  NSObject
objc[29984]: [0x10480d3a8]       0x101338f70  NSObject
objc[29984]: [0x10480d3b0]       0x101338f80  NSObject
objc[29984]: [0x10480d3b8]       0x101338f90  NSObject
objc[29984]: [0x10480d3c0]       0x101338fa0  NSObject
objc[29984]: [0x10480d3c8]       0x101338fb0  NSObject
objc[29984]: [0x10480d3d0]       0x101338fc0  NSObject
objc[29984]: [0x10480d3d8]       0x101338fd0  NSObject
objc[29984]: [0x10480d3e0]       0x101338fe0  NSObject
objc[29984]: [0x10480d3e8]       0x101338ff0  NSObject
objc[29984]: [0x10480d3f0]       0x101339000  NSObject
objc[29984]: [0x10480d3f8]       0x101339010  NSObject
objc[29984]: [0x10480d400]       0x101339020  NSObject
objc[29984]: [0x10480d408]       0x101339030  NSObject
objc[29984]: [0x10480d410]       0x101339040  NSObject
objc[29984]: [0x10480d418]       0x101339050  NSObject
objc[29984]: [0x10480d420]       0x101339060  NSObject
objc[29984]: [0x10480d428]       0x101339070  NSObject
objc[29984]: [0x10480d430]       0x101339080  NSObject
objc[29984]: [0x10480d438]       0x101339090  NSObject
objc[29984]: [0x10480d440]       0x1013390a0  NSObject
objc[29984]: [0x10480d448]       0x1013390b0  NSObject
objc[29984]: [0x10480d450]       0x1013390c0  NSObject
objc[29984]: [0x10480d458]       0x1013390d0  NSObject
objc[29984]: [0x10480d460]       0x1013390e0  NSObject
objc[29984]: [0x10480d468]       0x1013390f0  NSObject
objc[29984]: [0x10480d470]       0x101339100  NSObject
objc[29984]: [0x10480d478]       0x101339110  NSObject
objc[29984]: [0x10480d480]       0x101339120  NSObject
objc[29984]: [0x10480d488]       0x101339130  NSObject
objc[29984]: [0x10480d490]       0x101339140  NSObject
objc[29984]: [0x10480d498]       0x101339150  NSObject
objc[29984]: [0x10480d4a0]       0x101339160  NSObject
objc[29984]: [0x10480d4a8]       0x101339170  NSObject
objc[29984]: [0x10480d4b0]       0x101339180  NSObject
objc[29984]: [0x10480d4b8]       0x101339190  NSObject
objc[29984]: [0x10480d4c0]       0x1013391a0  NSObject
objc[29984]: [0x10480d4c8]       0x1013391b0  NSObject
objc[29984]: [0x10480d4d0]       0x1013391c0  NSObject
objc[29984]: [0x10480d4d8]       0x1013391d0  NSObject
objc[29984]: [0x10480d4e0]       0x1013391e0  NSObject
objc[29984]: [0x10480d4e8]       0x1013391f0  NSObject
objc[29984]: [0x10480d4f0]       0x101339200  NSObject
objc[29984]: [0x10480d4f8]       0x101339210  NSObject
objc[29984]: [0x10480d500]       0x101339220  NSObject
objc[29984]: [0x10480d508]       0x101339230  NSObject
objc[29984]: [0x10480d510]       0x101339240  NSObject
objc[29984]: [0x10480d518]       0x101339250  NSObject
objc[29984]: [0x10480d520]       0x101339260  NSObject
objc[29984]: [0x10480d528]       0x101339270  NSObject
objc[29984]: [0x10480d530]       0x101339280  NSObject
objc[29984]: [0x10480d538]       0x101339290  NSObject
objc[29984]: [0x10480d540]       0x1013392a0  NSObject
objc[29984]: [0x10480d548]       0x1013392b0  NSObject
objc[29984]: [0x10480d550]       0x1013392c0  NSObject
objc[29984]: [0x10480d558]       0x1013392d0  NSObject
objc[29984]: [0x10480d560]       0x1013392e0  NSObject
objc[29984]: [0x10480d568]       0x1013392f0  NSObject
objc[29984]: [0x10480d570]       0x101339300  NSObject
objc[29984]: [0x10480d578]       0x101339310  NSObject
objc[29984]: [0x10480d580]       0x101339320  NSObject
objc[29984]: [0x10480d588]       0x101339330  NSObject
objc[29984]: [0x10480d590]       0x101339340  NSObject
objc[29984]: [0x10480d598]       0x101339350  NSObject
objc[29984]: [0x10480d5a0]       0x101339360  NSObject
objc[29984]: [0x10480d5a8]       0x101339370  NSObject
objc[29984]: [0x10480d5b0]       0x101339380  NSObject
objc[29984]: [0x10480d5b8]       0x101339390  NSObject
objc[29984]: [0x10480d5c0]       0x1013393a0  NSObject
objc[29984]: [0x10480d5c8]       0x1013393b0  NSObject
objc[29984]: [0x10480d5d0]       0x1013393c0  NSObject
objc[29984]: [0x10480d5d8]       0x1013393d0  NSObject
objc[29984]: [0x10480d5e0]       0x1013393e0  NSObject
objc[29984]: [0x10480d5e8]       0x1013393f0  NSObject
objc[29984]: [0x10480d5f0]       0x101339400  NSObject
objc[29984]: [0x10480d5f8]       0x101339410  NSObject
objc[29984]: [0x10480d600]       0x101339420  NSObject
objc[29984]: [0x10480d608]       0x101339430  NSObject
objc[29984]: [0x10480d610]       0x101339440  NSObject
objc[29984]: [0x10480d618]       0x101339450  NSObject
objc[29984]: [0x10480d620]       0x101339460  NSObject
objc[29984]: [0x10480d628]       0x101339470  NSObject
objc[29984]: [0x10480d630]       0x101339480  NSObject
objc[29984]: [0x10480d638]       0x101339490  NSObject
objc[29984]: [0x10480d640]       0x1013394a0  NSObject
objc[29984]: [0x10480d648]       0x1013394b0  NSObject
objc[29984]: [0x10480d650]       0x1013394c0  NSObject
objc[29984]: [0x10480d658]       0x1013394d0  NSObject
objc[29984]: [0x10480d660]       0x1013394e0  NSObject
objc[29984]: [0x10480d668]       0x1013394f0  NSObject
objc[29984]: [0x10480d670]       0x101339500  NSObject
objc[29984]: [0x10480d678]       0x101339510  NSObject
objc[29984]: [0x10480d680]       0x101339520  NSObject
objc[29984]: [0x10480d688]       0x101339530  NSObject
objc[29984]: [0x10480d690]       0x101339540  NSObject
objc[29984]: [0x10480d698]       0x101339550  NSObject
objc[29984]: [0x10480d6a0]       0x101339560  NSObject
objc[29984]: [0x10480d6a8]       0x101339570  NSObject
objc[29984]: [0x10480d6b0]       0x101339580  NSObject
objc[29984]: [0x10480d6b8]       0x101339590  NSObject
objc[29984]: [0x10480d6c0]       0x1013395a0  NSObject
objc[29984]: [0x10480d6c8]       0x1013395b0  NSObject
objc[29984]: [0x10480d6d0]       0x1013395c0  NSObject
objc[29984]: [0x10480d6d8]       0x1013395d0  NSObject
objc[29984]: [0x10480d6e0]       0x1013395e0  NSObject
objc[29984]: [0x10480d6e8]       0x1013395f0  NSObject
objc[29984]: [0x10480d6f0]       0x101339600  NSObject
objc[29984]: [0x10480d6f8]       0x101339610  NSObject
objc[29984]: [0x10480d700]       0x101339620  NSObject
objc[29984]: [0x10480d708]       0x101339630  NSObject
objc[29984]: [0x10480d710]       0x101339640  NSObject
objc[29984]: [0x10480d718]       0x101339650  NSObject
objc[29984]: [0x10480d720]       0x101339660  NSObject
objc[29984]: [0x10480d728]       0x101339670  NSObject
objc[29984]: [0x10480d730]       0x101339680  NSObject
objc[29984]: [0x10480d738]       0x101339690  NSObject
objc[29984]: [0x10480d740]       0x1013396a0  NSObject
objc[29984]: [0x10480d748]       0x1013396b0  NSObject
objc[29984]: [0x10480d750]       0x1013396c0  NSObject
objc[29984]: [0x10480d758]       0x1013396d0  NSObject
objc[29984]: [0x10480d760]       0x1013396e0  NSObject
objc[29984]: [0x10480d768]       0x1013396f0  NSObject
objc[29984]: [0x10480d770]       0x101339700  NSObject
objc[29984]: [0x10480d778]       0x101339710  NSObject
objc[29984]: [0x10480d780]       0x101339720  NSObject
objc[29984]: [0x10480d788]       0x101339730  NSObject
objc[29984]: [0x10480d790]       0x101339740  NSObject
objc[29984]: [0x10480d798]       0x101339750  NSObject
objc[29984]: [0x10480d7a0]       0x101339760  NSObject
objc[29984]: [0x10480d7a8]       0x101339770  NSObject
objc[29984]: [0x10480d7b0]       0x101339780  NSObject
objc[29984]: [0x10480d7b8]       0x101339790  NSObject
objc[29984]: [0x10480d7c0]       0x1013397a0  NSObject
objc[29984]: [0x10480d7c8]       0x1013397b0  NSObject
objc[29984]: [0x10480d7d0]       0x1013397c0  NSObject
objc[29984]: [0x10480d7d8]       0x1013397d0  NSObject
objc[29984]: [0x10480d7e0]       0x1013397e0  NSObject
objc[29984]: [0x10480d7e8]       0x1013397f0  NSObject
objc[29984]: [0x10480d7f0]       0x101339800  NSObject
objc[29984]: [0x10480d7f8]       0x101339810  NSObject
objc[29984]: [0x10480d800]       0x101339820  NSObject
objc[29984]: [0x10480d808]       0x101339830  NSObject
objc[29984]: [0x10480d810]       0x101339840  NSObject
objc[29984]: [0x10480d818]       0x101339850  NSObject
objc[29984]: [0x10480d820]       0x101339860  NSObject
objc[29984]: [0x10480d828]       0x101339870  NSObject
objc[29984]: [0x10480d830]       0x101339880  NSObject
objc[29984]: [0x10480d838]       0x101339890  NSObject
objc[29984]: [0x10480d840]       0x1013398a0  NSObject
objc[29984]: [0x10480d848]       0x1013398b0  NSObject
objc[29984]: [0x10480d850]       0x1013398c0  NSObject
objc[29984]: [0x10480d858]       0x1013398d0  NSObject
objc[29984]: [0x10480d860]       0x1013398e0  NSObject
objc[29984]: [0x10480d868]       0x1013398f0  NSObject
objc[29984]: [0x10480d870]       0x101339900  NSObject
objc[29984]: [0x10480d878]       0x101339910  NSObject
objc[29984]: [0x10480d880]       0x101339920  NSObject
objc[29984]: [0x10480d888]       0x101339930  NSObject
objc[29984]: [0x10480d890]       0x101339940  NSObject
objc[29984]: [0x10480d898]       0x101339950  NSObject
objc[29984]: [0x10480d8a0]       0x101339960  NSObject
objc[29984]: [0x10480d8a8]       0x101339970  NSObject
objc[29984]: [0x10480d8b0]       0x101339980  NSObject
objc[29984]: [0x10480d8b8]       0x101339990  NSObject
objc[29984]: [0x10480d8c0]       0x1013399a0  NSObject
objc[29984]: [0x10480d8c8]       0x1013399b0  NSObject
objc[29984]: [0x10480d8d0]       0x1013399c0  NSObject
objc[29984]: [0x10480d8d8]       0x1013399d0  NSObject
objc[29984]: [0x10480d8e0]       0x1013399e0  NSObject
objc[29984]: [0x10480d8e8]       0x1013399f0  NSObject
objc[29984]: [0x10480d8f0]       0x101339a00  NSObject
objc[29984]: [0x10480d8f8]       0x101339a10  NSObject
objc[29984]: [0x10480d900]       0x101339a20  NSObject
objc[29984]: [0x10480d908]       0x101339a30  NSObject
objc[29984]: [0x10480d910]       0x101339a40  NSObject
objc[29984]: [0x10480d918]       0x101339a50  NSObject
objc[29984]: [0x10480d920]       0x101339a60  NSObject
objc[29984]: [0x10480d928]       0x101339a70  NSObject
objc[29984]: [0x10480d930]       0x101339a80  NSObject
objc[29984]: [0x10480d938]       0x101339a90  NSObject
objc[29984]: [0x10480d940]       0x101339aa0  NSObject
objc[29984]: [0x10480d948]       0x101339ab0  NSObject
objc[29984]: [0x10480d950]       0x101339ac0  NSObject
objc[29984]: [0x10480d958]       0x101339ad0  NSObject
objc[29984]: [0x10480d960]       0x101339ae0  NSObject
objc[29984]: [0x10480d968]       0x101339af0  NSObject
objc[29984]: [0x10480d970]       0x101339b00  NSObject
objc[29984]: [0x10480d978]       0x101339b10  NSObject
objc[29984]: [0x10480d980]       0x101339b20  NSObject
objc[29984]: [0x10480d988]       0x101339b30  NSObject
objc[29984]: [0x10480d990]       0x101339b40  NSObject
objc[29984]: [0x10480d998]       0x101339b50  NSObject
objc[29984]: [0x10480d9a0]       0x101339b60  NSObject
objc[29984]: [0x10480d9a8]       0x101339b70  NSObject
objc[29984]: [0x10480d9b0]       0x101339b80  NSObject
objc[29984]: [0x10480d9b8]       0x101339b90  NSObject
objc[29984]: [0x10480d9c0]       0x101339ba0  NSObject
objc[29984]: [0x10480d9c8]       0x101339bb0  NSObject
objc[29984]: [0x10480d9d0]       0x101339bc0  NSObject
objc[29984]: [0x10480d9d8]       0x101339bd0  NSObject
objc[29984]: [0x10480d9e0]       0x101339be0  NSObject
objc[29984]: [0x10480d9e8]       0x101339bf0  NSObject
objc[29984]: [0x10480d9f0]       0x101339c00  NSObject
objc[29984]: [0x10480d9f8]       0x101339c10  NSObject
objc[29984]: [0x10480da00]       0x101339c20  NSObject
objc[29984]: [0x10480da08]       0x101339c30  NSObject
objc[29984]: [0x10480da10]       0x101339c40  NSObject
objc[29984]: [0x10480da18]       0x101339c50  NSObject
objc[29984]: [0x10480da20]       0x101339c60  NSObject
objc[29984]: [0x10480da28]       0x101339c70  NSObject
objc[29984]: [0x10480da30]       0x101339c80  NSObject
objc[29984]: [0x10480da38]       0x101339c90  NSObject
objc[29984]: [0x10480da40]       0x101339ca0  NSObject
objc[29984]: [0x10480da48]       0x101339cb0  NSObject
objc[29984]: [0x10480da50]       0x101339cc0  NSObject
objc[29984]: [0x10480da58]       0x101339cd0  NSObject
objc[29984]: [0x10480da60]       0x101339ce0  NSObject
objc[29984]: [0x10480da68]       0x101339cf0  NSObject
objc[29984]: [0x10480da70]       0x101339d00  NSObject
objc[29984]: [0x10480da78]       0x101339d10  NSObject
objc[29984]: [0x10480da80]       0x101339d20  NSObject
objc[29984]: [0x10480da88]       0x101339d30  NSObject
objc[29984]: [0x10480da90]       0x101339d40  NSObject
objc[29984]: [0x10480da98]       0x101339d50  NSObject
objc[29984]: [0x10480daa0]       0x101339d60  NSObject
objc[29984]: [0x10480daa8]       0x101339d70  NSObject
objc[29984]: [0x10480dab0]       0x101339d80  NSObject
objc[29984]: [0x10480dab8]       0x101339d90  NSObject
objc[29984]: [0x10480dac0]       0x101339da0  NSObject
objc[29984]: [0x10480dac8]       0x101339db0  NSObject
objc[29984]: [0x10480dad0]       0x101339dc0  NSObject
objc[29984]: [0x10480dad8]       0x101339dd0  NSObject
objc[29984]: [0x10480dae0]       0x101339de0  NSObject
objc[29984]: [0x10480dae8]       0x101339df0  NSObject
objc[29984]: [0x10480daf0]       0x101339e00  NSObject
objc[29984]: [0x10480daf8]       0x101339e10  NSObject
objc[29984]: [0x10480db00]       0x101339e20  NSObject
objc[29984]: [0x10480db08]       0x101339e30  NSObject
objc[29984]: [0x10480db10]       0x101339e40  NSObject
objc[29984]: [0x10480db18]       0x101339e50  NSObject
objc[29984]: [0x10480db20]       0x101339e60  NSObject
objc[29984]: [0x10480db28]       0x101339e70  NSObject
objc[29984]: [0x10480db30]       0x101339e80  NSObject
objc[29984]: [0x10480db38]       0x101339e90  NSObject
objc[29984]: [0x10480db40]       0x101339ea0  NSObject
objc[29984]: [0x10480db48]       0x101339eb0  NSObject
objc[29984]: [0x10480db50]       0x101339ec0  NSObject
objc[29984]: [0x10480db58]       0x101339ed0  NSObject
objc[29984]: [0x10480db60]       0x101339ee0  NSObject
objc[29984]: [0x10480db68]       0x101339ef0  NSObject
objc[29984]: [0x10480db70]       0x101339f00  NSObject
objc[29984]: [0x10480db78]       0x101339f10  NSObject
objc[29984]: [0x10480db80]       0x101339f20  NSObject
objc[29984]: [0x10480db88]       0x101339f30  NSObject
objc[29984]: [0x10480db90]       0x101339f40  NSObject
objc[29984]: [0x10480db98]       0x101339f50  NSObject
objc[29984]: [0x10480dba0]       0x101339f60  NSObject
objc[29984]: [0x10480dba8]       0x101339f70  NSObject
objc[29984]: [0x10480dbb0]       0x101339f80  NSObject
objc[29984]: [0x10480dbb8]       0x101339f90  NSObject
objc[29984]: [0x10480dbc0]       0x101339fa0  NSObject
objc[29984]: [0x10480dbc8]       0x101339fb0  NSObject
objc[29984]: [0x10480dbd0]       0x101339fc0  NSObject
objc[29984]: [0x10480dbd8]       0x101339fd0  NSObject
objc[29984]: [0x10480dbe0]       0x101339fe0  NSObject
objc[29984]: [0x10480dbe8]       0x101339ff0  NSObject
objc[29984]: [0x10480dbf0]       0x10133a000  NSObject
objc[29984]: [0x10480dbf8]       0x10133a010  NSObject
objc[29984]: [0x10480dc00]       0x10133a020  NSObject
objc[29984]: [0x10480dc08]       0x10133a030  NSObject
objc[29984]: [0x10480dc10]       0x10133a040  NSObject
objc[29984]: [0x10480dc18]       0x10133a050  NSObject
objc[29984]: [0x10480dc20]       0x10133a060  NSObject
objc[29984]: [0x10480dc28]       0x10133a070  NSObject
objc[29984]: [0x10480dc30]       0x10133a080  NSObject
objc[29984]: [0x10480dc38]       0x10133a090  NSObject
objc[29984]: [0x10480dc40]       0x10133a0a0  NSObject
objc[29984]: [0x10480dc48]       0x10133a0b0  NSObject
objc[29984]: [0x10480dc50]       0x10133a0c0  NSObject
objc[29984]: [0x10480dc58]       0x10133a0d0  NSObject
objc[29984]: [0x10480dc60]       0x10133a0e0  NSObject
objc[29984]: [0x10480dc68]       0x10133a0f0  NSObject
objc[29984]: [0x10480dc70]       0x10133a100  NSObject
objc[29984]: [0x10480dc78]       0x10133a110  NSObject
objc[29984]: [0x10480dc80]       0x10133a120  NSObject
objc[29984]: [0x10480dc88]       0x10133a130  NSObject
objc[29984]: [0x10480dc90]       0x10133a140  NSObject
objc[29984]: [0x10480dc98]       0x10133a150  NSObject
objc[29984]: [0x10480dca0]       0x10133a160  NSObject
objc[29984]: [0x10480dca8]       0x10133a170  NSObject
objc[29984]: [0x10480dcb0]       0x10133a180  NSObject
objc[29984]: [0x10480dcb8]       0x10133a190  NSObject
objc[29984]: [0x10480dcc0]       0x10133a1a0  NSObject
objc[29984]: [0x10480dcc8]       0x10133a1b0  NSObject
objc[29984]: [0x10480dcd0]       0x10133a1c0  NSObject
objc[29984]: [0x10480dcd8]       0x10133a1d0  NSObject
objc[29984]: [0x10480dce0]       0x10133a1e0  NSObject
objc[29984]: [0x10480dce8]       0x10133a1f0  NSObject
objc[29984]: [0x10480dcf0]       0x10133a200  NSObject
objc[29984]: [0x10480dcf8]       0x10133a210  NSObject
objc[29984]: [0x10480dd00]       0x10133a220  NSObject
objc[29984]: [0x10480dd08]       0x10133a230  NSObject
objc[29984]: [0x10480dd10]       0x10133a240  NSObject
objc[29984]: [0x10480dd18]       0x10133a250  NSObject
objc[29984]: [0x10480dd20]       0x10133a260  NSObject
objc[29984]: [0x10480dd28]       0x10133a270  NSObject
objc[29984]: [0x10480dd30]       0x10133a280  NSObject
objc[29984]: [0x10480dd38]       0x10133a290  NSObject
objc[29984]: [0x10480dd40]       0x10133a2a0  NSObject
objc[29984]: [0x10480dd48]       0x10133a2b0  NSObject
objc[29984]: [0x10480dd50]       0x10133a2c0  NSObject
objc[29984]: [0x10480dd58]       0x10133a2d0  NSObject
objc[29984]: [0x10480dd60]       0x10133a2e0  NSObject
objc[29984]: [0x10480dd68]       0x10133a2f0  NSObject
objc[29984]: [0x10480dd70]       0x101334f30  NSObject
objc[29984]: [0x10480dd78]       0x101334f40  NSObject
objc[29984]: [0x10480dd80]       0x101334f50  NSObject
objc[29984]: [0x10480dd88]       0x101334f60  NSObject
objc[29984]: [0x10480dd90]       0x101334f70  NSObject
objc[29984]: [0x10480dd98]       0x101334f80  NSObject
objc[29984]: [0x10480dda0]       0x101334f90  NSObject
objc[29984]: [0x10480dda8]       0x101334fa0  NSObject
objc[29984]: [0x10480ddb0]       0x101334fb0  NSObject
objc[29984]: [0x10480ddb8]       0x101334fc0  NSObject
objc[29984]: [0x10480ddc0]       0x101334fd0  NSObject
objc[29984]: [0x10480ddc8]       0x101334fe0  NSObject
objc[29984]: [0x10480ddd0]       0x101334ff0  NSObject
objc[29984]: [0x10480ddd8]       0x101335000  NSObject
objc[29984]: [0x10480dde0]       0x101335010  NSObject
objc[29984]: [0x10480dde8]       0x101335020  NSObject
objc[29984]: [0x10480ddf0]       0x101335030  NSObject
objc[29984]: [0x10480ddf8]       0x101335040  NSObject
objc[29984]: [0x10480de00]       0x101335050  NSObject
objc[29984]: [0x10480de08]       0x101335060  NSObject
objc[29984]: [0x10480de10]       0x101335070  NSObject
objc[29984]: [0x10480de18]       0x101335080  NSObject
objc[29984]: [0x10480de20]       0x101335090  NSObject
objc[29984]: [0x10480de28]       0x1013350a0  NSObject
objc[29984]: [0x10480de30]       0x1013350b0  NSObject
objc[29984]: [0x10480de38]       0x1013350c0  NSObject
objc[29984]: [0x10480de40]       0x1013350d0  NSObject
objc[29984]: [0x10480de48]       0x1013350e0  NSObject
objc[29984]: [0x10480de50]       0x1013350f0  NSObject
objc[29984]: [0x10480de58]       0x101335100  NSObject
objc[29984]: [0x10480de60]       0x101335110  NSObject
objc[29984]: [0x10480de68]       0x101335120  NSObject
objc[29984]: [0x10480de70]       0x101335130  NSObject
objc[29984]: [0x10480de78]       0x101335140  NSObject
objc[29984]: [0x10480de80]       0x101335150  NSObject
objc[29984]: [0x10480de88]       0x101335160  NSObject
objc[29984]: [0x10480de90]       0x101335170  NSObject
objc[29984]: [0x10480de98]       0x101335180  NSObject
objc[29984]: [0x10480dea0]       0x101335190  NSObject
objc[29984]: [0x10480dea8]       0x1013351a0  NSObject
objc[29984]: [0x10480deb0]       0x1013351b0  NSObject
objc[29984]: [0x10480deb8]       0x1013351c0  NSObject
objc[29984]: [0x10480dec0]       0x1013351d0  NSObject
objc[29984]: [0x10480dec8]       0x1013351e0  NSObject
objc[29984]: [0x10480ded0]       0x1013351f0  NSObject
objc[29984]: [0x10480ded8]       0x101335200  NSObject
objc[29984]: [0x10480dee0]       0x101335210  NSObject
objc[29984]: [0x10480dee8]       0x101335220  NSObject
objc[29984]: [0x10480def0]       0x101335230  NSObject
objc[29984]: [0x10480def8]       0x101335240  NSObject
objc[29984]: [0x10480df00]       0x101335250  NSObject
objc[29984]: [0x10480df08]       0x101335260  NSObject
objc[29984]: [0x10480df10]       0x101335270  NSObject
objc[29984]: [0x10480df18]       0x101335280  NSObject
objc[29984]: [0x10480df20]       0x101335290  NSObject
objc[29984]: [0x10480df28]       0x1013352a0  NSObject
objc[29984]: [0x10480df30]       0x1013352b0  NSObject
objc[29984]: [0x10480df38]       0x1013352c0  NSObject
objc[29984]: [0x10480df40]       0x1013352d0  NSObject
objc[29984]: [0x10480df48]       0x1013352e0  NSObject
objc[29984]: [0x10480df50]       0x1013352f0  NSObject
objc[29984]: [0x10480df58]       0x101335300  NSObject
objc[29984]: [0x10480df60]       0x101335310  NSObject
objc[29984]: [0x10480df68]       0x101335320  NSObject
objc[29984]: [0x10480df70]       0x101335330  NSObject
objc[29984]: [0x10480df78]       0x101335340  NSObject
objc[29984]: [0x10480df80]       0x101335350  NSObject
objc[29984]: [0x10480df88]       0x101335360  NSObject
objc[29984]: [0x10480df90]       0x101335370  NSObject
objc[29984]: [0x10480df98]       0x101335380  NSObject
objc[29984]: [0x10480dfa0]       0x101335390  NSObject
objc[29984]: [0x10480dfa8]       0x1013353a0  NSObject
objc[29984]: [0x10480dfb0]       0x1013353b0  NSObject
objc[29984]: [0x10480dfb8]       0x1013353c0  NSObject
objc[29984]: [0x10480dfc0]       0x1013353d0  NSObject
objc[29984]: [0x10480dfc8]       0x1013353e0  NSObject
objc[29984]: [0x10480dfd0]       0x1013353f0  NSObject
objc[29984]: [0x10480dfd8]       0x101335400  NSObject
objc[29984]: [0x10480dfe0]       0x101335410  NSObject
objc[29984]: [0x10480dfe8]       0x101335420  NSObject
objc[29984]: [0x10480dff0]       0x101335430  NSObject
objc[29984]: [0x10480dff8]       0x101335440  NSObject
objc[29984]: [0x104809000]  ................  PAGE  (hot) 
objc[29984]: [0x104809038]       0x101335450  NSObject

我们看到这里有产生PAGE (hot) ,我们再以下两行打印

objc[29984]: [0x10480d000]  ................  PAGE (full)  (cold)
objc[29984]: [0x104809000]  ................  PAGE  (hot) 

当前页满的时候,新建了一个PAGE,并设置hot
这里可能看出504刚好满一页,我们算下,页面的大小 是多少?
504 8 + 56=4088+8(哨兵对象)=4096=10244=4k
通过这里可以看出PAGESIZE在MAC下是4k。
我们再看下AutoreleasePoolPage中的#define PAGE_MIN_SIZE (1 << PAGE_MIN_SHIFT),而#define PAGE_MIN_SHIFT 12,1左移12位,也就是2的12次方,就是4096。iOS是16k的在大小
在分页的时候哨兵对象并没有创建,因为我们已经有一个了,不需要再创建。
所以第二个对象就可以创建505个对象了。

那我们的pop是如何操作的,我们来看下objc_autoreleasePoolPop函数

void
objc_autoreleasePoolPop(void *ctxt)
{
    AutoreleasePoolPage::pop(ctxt);
}

我们再看一这里的pop函数

 static inline void
    pop(void *token)
    {
        AutoreleasePoolPage *page;
        id *stop;
        if (token == (void*)EMPTY_POOL_PLACEHOLDER) {
            // Popping the top-level placeholder pool.
            page = hotPage();
            if (!page) {
                // Pool was never used. Clear the placeholder.
                return setHotPage(nil);
            }
            // Pool was used. Pop its contents normally.
            // Pool pages remain allocated for re-use as usual.
            page = coldPage();
            token = page->begin();
        } else {
            page = pageForPointer(token);
        }

        stop = (id *)token;
        if (*stop != POOL_BOUNDARY) {
            if (stop == page->begin()  &&  !page->parent) {
                // Start of coldest page may correctly not be POOL_BOUNDARY:
                // 1. top-level pool is popped, leaving the cold page in place
                // 2. an object is autoreleased with no pool
            } else {
                // Error. For bincompat purposes this is not 
                // fatal in executables built with old SDKs.
                return badPop(token);
            }
        }

        if (slowpath(PrintPoolHiwat || DebugPoolAllocation || DebugMissingPools)) {
            return popPageDebug(token, page, stop);
        }

        return popPage(token, page, stop);
    }

这里获取到page = hotPage();这个hot页,如果不是hot。

 if (!page) {
                // Pool was never used. Clear the placeholder.
                return setHotPage(nil);
            }

置空

 page = coldPage();
 token = page->begin();

不断的移动这个页面,移除popPage(token, page, stop);这里的调用

 template
    static void
    popPage(void *token, AutoreleasePoolPage *page, id *stop)
    {
        if (allowDebug && PrintPoolHiwat) printHiwat();

        page->releaseUntil(stop);

        // memory: delete empty children
        if (allowDebug && DebugPoolAllocation  &&  page->empty()) {
            // special case: delete everything during page-per-pool debugging
            AutoreleasePoolPage *parent = page->parent;
            page->kill();
            setHotPage(parent);
        } else if (allowDebug && DebugMissingPools  &&  page->empty()  &&  !page->parent) {
            // special case: delete everything for pop(top)
            // when debugging missing autorelease pools
            page->kill();
            setHotPage(nil);
        } else if (page->child) {
            // hysteresis: keep one empty child if page is more than half full
            if (page->lessThanHalfFull()) {
                page->child->kill();
            }
            else if (page->child->child) {
                page->child->child->kill();
            }
        }
    }

这里先

AutoreleasePoolPage *parent = page->parent;

拿到parent页面,接着

page->kill();

杀掉当前页,然后

setHotPage(parent);

把父页设置成hot。
而kill就是不断的内存平移

 void kill() 
    {
        // Not recursive: we don't want to blow out the stack 
        // if a thread accumulates a stupendous amount of garbage
        AutoreleasePoolPage *page = this;
        while (page->child) page = page->child;

        AutoreleasePoolPage *deathptr;
        do {
            deathptr = page;
            page = page->parent;
            if (page) {
                page->unprotect();
                page->child = nil;
                page->protect();
            }
            delete deathptr;
        } while (deathptr != this);
    }

先入后出,不断的递归。
通过哨兵对象是否等于哨兵边界来判断标记完成了。

5 自动释放池的拓展

  • 临时变量什么时候释放
  • 自动释放池原理
  • 自动释放池能否嵌套使用
    临时变量什么时候释放就是在作用域的范围
    自动释放池原理就是上述所讲
    自动释放池可以嵌套使用
    我们看下代码
#import 
extern void _objc_autoreleasePoolPrint(void);

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSObject *objc = [[[NSObject alloc] init] autorelease];
        
        @autoreleasepool {
            NSObject *objc2 = [[[NSObject alloc] init] autorelease];
            NSLog(@"%@", objc2);
            _objc_autoreleasePoolPrint();
        }
        
        _objc_autoreleasePoolPrint();

    }
    return 0;
}

我们运行下项目,看下效果,如下

objc[30334]: ##############
objc[30334]: AUTORELEASE POOLS for thread 0x1000ebe00
objc[30334]: 4 releases pending.
objc[30334]: [0x100811000]  ................  PAGE  (hot) (cold)
objc[30334]: [0x100811038]  ################  POOL 0x100811038
objc[30334]: [0x100811040]       0x10060d9b0  NSObject
objc[30334]: [0x100811048]  ################  POOL 0x100811048
objc[30334]: [0x100811050]       0x10060cdd0  NSObject
objc[30334]: ##############
objc[30334]: ##############
objc[30334]: AUTORELEASE POOLS for thread 0x1000ebe00
objc[30334]: 2 releases pending.
objc[30334]: [0x100811000]  ................  PAGE  (hot) (cold)
objc[30334]: [0x100811038]  ################  POOL 0x100811038
objc[30334]: [0x100811040]       0x10060d9b0  NSObject
objc[30334]: ##############
KCObjcBuild was compiled with optimization - stepping may behave oddly; variables may not be available.

从这可以看出objc2是加入到objc2的自动释放池中,这里也说明是可以嵌套使用,相互不影响。
但是如果不autorelease是不加入到自动释放池中的(在MAC中)
但是以alloc、new、copy、mutablecopy创建的是不会加入到自动释放池中的

总结

这篇文章主要介绍了自动释放池的结构、创建、压栈等相关知识, 到这里内存管理的相关知识,我们已经基本介绍完了,但这只是个人的一份见解,内存相关的知识还有很多很多,本人也只是对其有那么一点点的研究,如有遗漏,还望海涵。

你可能感兴趣的:(iOS-内存管理分析(下))