iOS日记5-autoreleasepool和autorelease

1.autoreleasePool的具体使用

MRC:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
id obj = [[NSObject alloc] init];
[obj autorelease];
[pool drain];  //调用[obj release] 
ARC和MRC:
@autoreleasepool {
  id obj = [[NSObject alloc] init];
}

2.autoreleasepool原理

1)与NSRunLoop的关系

每一个线程(包括主线程)都有一个NSAutoreleasePool栈. 当一个新的池子被创建的时候, push进栈. 当池子被释放内存时, pop出栈. 对象调用autorelease方法进入栈顶的池子中. 当线程结束的时候, 它会自动地销毁掉所有跟它有关联的池子.
在当前的runloop迭代中,系统会加入autoreleasepool的push和pop操作,用于管理对象。

2)内部实现

这里涉及到了一个AutoreleasePoolPage类。

//非完整实现
struct AutoreleasePoolPage {
  magic_t const magic;
  id *next;
  pthread_ const thread;
  AutoreleasePoolPage *const parent;
  AutoreleasePoolPage *child;
  uint32_t const depth;
  uint32_t hiwat;
}
  • AutoreleasePool并没有单独的结构,而是由若干个AutoreleasePoolPage以双向链表的形式组合而成(分别对应结构中的parent指针和child指针)
  • AutoreleasePool是按线程一一对应的(结构中的thread指针指向当前线程)
  • AutoreleasePoolPage每个对象会开辟4096字节内存(也就是虚拟内存一页的大小),除了上面的实例变量所占空间,剩下的空间全部用来储存autorelease对象的地址
  • 上面的id *next指针作为游标指向栈顶最新add进来的autorelease对象的下一个位置
  • 一个AutoreleasePoolPage的空间被占满时,会新建一个AutoreleasePoolPage对象,连接链表,后来的autorelease对象在新的page加入

使用@autoreleasepool{ }时,编译器将其改写为:

void *context = objc_autoreleasePoolPush();  //作为一个记录点,每一次的释放会将2个记录点内的对象都释放,直到完全释放
//some codes
objc_autoreleasePoolPop(context);

3.需要手动创建autoreleasepool的时候

  • 1.写的程序不是基于UIFrameWork,例如命令行项目
  • 2.写的循环大量创建临时对象。可以在循环中创建autoreleasepool,在池子中创建对象。这样有助于降低内存峰值
  • 3.创建了一个新的线程,线程开始执行时,需要立刻创建一个autoreleasepool

4.参考资料

http://blog.sunnyxx.com/2014/10/15/behind-autorelease/
http://www.jianshu.com/p/5559bc15490d
《Objective-C高级编程:ios与OS X多线程和内存管理》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 好记性不如烂笔头,勿在浮沙筑高台,不积跬步无以至千里,做人做事要有安排有计划。 内存管理一直是学习 Objecti...
    BigLuckyHaha阅读 7,104评论 9 19
  • 一、官网关于自动释放池的说明截取 NSAutoreleasePool NSAutoreleasePool 类被用来...
    Mitchell阅读 14,023评论 5 40
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,200评论 30 471
  • 11.看下面的程序,第一个NSLog会输出什么?这时str的retainCount是多少?第二个和第三个呢? 为什...
    AlanGe阅读 746评论 1 4
  • 1、[NSObject alloc]在创建完对象后,会让该对象的retainCount+1,后续的init为初始化...
    naiyi阅读 1,554评论 0 4