AutoreleasePool(自动释放法)在OC中的一种内存自动回收机制,它可以延迟加入AutoreleasePool中的变量release的时机.在正常情况下,创建的变量会在超出其作用域的时候release,但是如果将变量加入AutoreleasePool,那么release将延迟执行.
AutoreleasePool创建和释放
- app启动后,苹果在主线程RunLoop里注册了两个Observe,其回调都是_wrapRunLoopWithAutoreleasePoolHandler().
- 第一个Observe监视的事件是Entry(即将进入loop),其回调内会调用_objc_autoreleasePoolPush()创建自动释放池,其order是-2147483647,优先级最高,保证创建释放池发送在其他回调之前
- 第二个Observer监视了两个事件:BeforeWaiting(准备进入休眠)时调用_objc_autoreleasePoolPop()和_objc_autoreleasePush()释放旧的池并创建新的池,Exit(即将退出Loop)时调用_objc_autoreleasePoolPush()来释放自动释放池这个Observer的order是2147483647,优先级最低,保证其释放池发生在其他回调之后.
- 在主线程执行的代码,通常是写在诸如事件回调,Timer回调内的,这些回调会被RunLoop创建好的autorelease环绕着,所以不会出现内存泄露,开发者也不必显式创建pool了
也就是说AutoreleasePool创建是在一个RunLoop事件开始之前(Push),AutoreleasePool释放是在一个RunLoop事件即将结束之前(Pop).
AutoreleasePool里的Autorelease对象的加入是在RunLoop事件中,AutoreleasePool里的Autorelease对象的释放是在AutoreleasePool释放时.
用途: 苹果官方文档说:
①如果你编写的程序不是基于UI框架,比如说命令行工具;
②如果是你编写的循环中创建了大量的临时对象;
③如果你创建了一个辅助线程.
官方提供的Demo:
NSArray *urls = <# An array of file URLs #>;
for (NSURL *url in urls){
@autoreleasepool{
NSError * error;
NSString * fileContents = [NSString stringWithContentsOfURL: url encoding: NSUTF8StringEncoding error: &error];
/* Process the string, creating and autoreleasesing more objects. */
}
}
这里写了一个Demo,测试使用autoreleasepool的内存占用情况
加了@autoreleasepool内存稳定在73M,不使用autoreleasepool的会出现暴增的情况,所以autoreleasepool还是挺有用的
static const int kStep = 50000;
static const int kIterationCount = 10 * kStep;
//查看app运行内存
-(void)obserMemoryUsage{
NSNumber *num = nil;
NSString *str = nil;
for (int i=0; i<kIterationCount; i++){
@autoreleasepool{
num = [NSNumber numberWithInt: i];
str = [NSString stringWithFormat:@"test"];
[NSString stringWithFormat: @"%@%@", num, str];
if (i%kStep == 0){
double ff = getMemoryUsage();
NSLog(@"%f", ff);
}
}
}
}
double getMemoryUsage(void){
struct task_basic_info info;
mach_msg_type_number_t size = sizeof(info);
kern_return_t kerr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size);
double memoryUsageInMB = kerr == KERN_SUCCESS ? (info.resident_size/1024.0/1024.0) : 0.0;
return memoryUsageInMB;
}
网友评论