iOS | autoreleasePool的实现

  • 每一个线程的autorelease就是一个指针的堆栈。

  • 每一个指针代表一个要release的对象或者是POOL_SENTINEL(哨兵对象,代表一个autorelease的边界,释放一个autorelease pool需要将哨兵对象后的所有release节点对象释放)。

  • 每一个pool token代表的就是这个pool所对应的POOL_SENTINEL的结点的内存位置,当这个pool被pop后,这个token后的所有的结点对应的对象内存都会被释放。

  • autoreleasePool的实现是通过AutoreleasePage结点实现的()

  • 这个堆栈被划分成了一个以page为结点的双向链表。pages会在必要的时候动态增加或者删除

  • Thread_local storage(线程局部存储)指向hot page,即最新添加的autoreleased对象所在的那个page。

AutoreleasePoolPage内存结构如下所示:

iOS | autoreleasePool的实现

  1. magic 用来校验 AutoreleasePoolPage 的结构是否完整;

  2. next 指向最新添加的 autoreleased 对象的下一个位置,初始化时指向 begin() ;

  3. thread 指向当前线程;

  4. parent 指向父结点,第一个结点的 parent 值为 nil ;

  5. child 指向子结点,最后一个结点的 child 值为 nil ;

  6. depth 代表深度,从 0 开始,往后递增 1;

  7. hiwat 代表 high water mark 。

  8. 当 next == begin() 时,表示 AutoreleasePoolPage 为空;当 next == end() 时,表示 AutoreleasePoolPage 已满。此时再创建一个AutoreleasePoolPage结点。

pool通过 pushpop 操作来添加autoreleasepool和移除autoreleasepool:

  • push操作实际就是前next指针添加一个哨兵,然后再往哨兵的next后添加这个pool要release的对象。
  • pop操作会将内存地址在 pool token 之后的所有 autoreleased 对象都会被 release 。直到 pool token 所在 page 的 next 指向 pool token 为止。

iOS | autoreleasePool的实现
此时,如果执行 pop(token1) 操作,那么该 autoreleasepool 堆栈的内存结构将会变成如下图所示:

iOS | autoreleasePool的实现
转载自:http://www.cocoachina.com/ios/20150610/12093.html