关于Autorelease和内存管理

​ MRC时代,对象的引用计数需要自己管理。创建一个对象后需要自己去释放,内存管理相当的繁琐,但对内存的控制会更有主动权,内存管理的理解更好。ARC时代来临后,对象何时去释放,越来越变得模糊。

引用计数

​ 对于用alloc/new/copy/mutableCopy方法生成并持有,或者retain都会使对象的引用计数加1,当引用计数为0时,对象会被销毁。MRC时代,对象的引用计数需要自己管理。创建一个对象后需要自己去释放,内存管理相当的繁琐,但对内存的控制会更有主动权,内存管理的理解更好。此外,对于一个对象如果调用了多次releasse会导致崩溃,崩溃的原因是对象已经被销毁,造成了野指针访问。

​ 系统采用散列表(引用计数表)管理引用计数。1.对象用内存块的分配无需考虑内存块头部。2.引用计数表各记录中存有内存块地址,可从各个记录追溯到各对象的内存块。

自动释放池

​ autorelease就是自动释放。是MRC时代的产物,它更类似于局部变量(自动变量),在变量超出作用域的时候自动废弃。但autorelease不会在超出作用域后立刻自动release。autorelease的对象会注册到autoreleasepool中,当autoreleasepool清理(drain)的时候将所有releasepool中的对象逐一release一次。

​ 一个iOS进程中系统会自动创建pool,在主线程runloop每次循环过程中都会废弃旧的pool,并创建新的。可知autorelease的对象并不是立刻销毁的,而是等到注册到的releasepool销毁的时候才能被销毁。

应用

​ 如果主线的在同步执行耗时任务时,releasepool就会堆积大量没有及时释放的对象,导致内存不足的情况。此情况需要自己添加autoreleasepool。

1
2
3
4
5
6
7
for (int i = 0; i < 10000000; i++) {
@autoreleasepool {
/*
* 生成对象
*/
}
}