关于@autoreleasepool的性能测试及手动释放自动释放池
2016-01-11 17:16
477 查看
原文地址:http://yangchao0033.github.io/blog/2015/12/31/guan-yu-at-autoreleasepoolde-ce-shi-ji-shi-yong/
首先,我们先对使用autoreleasepool的场景进行性能对比。
不用autoreleasepool
不使用性能如下如所示:
使用autoreleasepool
使用效果如下图所示:
综上,当需要在程序中创建大量的临时变量时(大量也可指数量多,不确定,比如从数据库中读取数据时),很容易使内存产生峰值又回到内存低谷,这样对程序的性能会产生很大影响,而使用自动释放池后,峰值明显有所下降。
而当autoreleasepool的右括号结束后,会对整个autoreleasepool做一次倾倒。但是这会使其中局部产生的大量零时变量无法及时释放,直到for循环结束后抵达main中autoreleasepool的右括号位置才能释放。这样会在局部位置发生内存峰值。
官方提出的解决方案是,在大量产生局部变量的位置用autoreleasepool代码块进行包装。比如for循环中要执行的语句,这样每次for循环结束后就会及时收回临时变量占用的内存空间。
这里的需求我们可以使用MRC时代的一个重量级的自动释放池,通常用来创建偶尔需要释放清空的池。
首先,我们先对使用autoreleasepool的场景进行性能对比。
不用autoreleasepool
- (void)doSomething { NSMutableArray *collection = @[].mutableCopy; for (int i = 0; i < 10e6; ++i) { NSString *str = [NSString stringWithFormat:@"hi + %d", i]; [collection addObject:str]; } NSLog(@"finished!"); }
不使用性能如下如所示:
使用autoreleasepool
- (void)doSomething { NSMutableArray *collection = @[].mutableCopy; for (int i = 0; i < 10e6; ++i) { @autoreleasepool { NSString *str = [NSString stringWithFormat:@"hi + %d", i]; [collection addObject:str]; } } NSLog(@"finished!"); }
使用效果如下图所示:
综上,当需要在程序中创建大量的临时变量时(大量也可指数量多,不确定,比如从数据库中读取数据时),很容易使内存产生峰值又回到内存低谷,这样对程序的性能会产生很大影响,而使用自动释放池后,峰值明显有所下降。
原因:由于在mian函数中已经为我们添加了自动释放池,如下所示:
#import <UIKit/UIKit.h> #import "AppDelegate.h" int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }
而当autoreleasepool的右括号结束后,会对整个autoreleasepool做一次倾倒。但是这会使其中局部产生的大量零时变量无法及时释放,直到for循环结束后抵达main中autoreleasepool的右括号位置才能释放。这样会在局部位置发生内存峰值。
官方提出的解决方案是,在大量产生局部变量的位置用autoreleasepool代码块进行包装。比如for循环中要执行的语句,这样每次for循环结束后就会及时收回临时变量占用的内存空间。
思考:如何在指定的次数时,及时释放自动释放池中的临时变量
使用mrc下的特性 在编译选项中,为MRC的程序添加-fno-objc-arc标记,表明在编译时,该文件使用MRC编译 如果要在MRC项目中添加ARC的文件,可以使用 -fobjc-arc 标记即可
这里的需求我们可以使用MRC时代的一个重量级的自动释放池,通常用来创建偶尔需要释放清空的池。
- (void)doSomething { int count = 0; NSMutableArray *collection = @[].mutableCopy; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; for (int i = 0; i < 10e6; ++i) { NSString *str = [NSString stringWithFormat:@"hi + %d", i]; [collection addObject:str]; if (++count == 100) { /** 每一百次倾倒一次池子 */ [pool drain]; count = 0; } } /** 用来倾倒当i的个数不是100的倍数时,比如读取数据库数据时,数据总数为不确定值 */ [pool drain]; NSLog(@"finished!"); }
相关文章推荐
- Java IO与NIO的一些文件拷贝测试
- 推荐六款WEB上传组件性能测试与比较第1/10页
- C#代码性能测试类(简单实用)
- asp 性能测试报告 学习asp朋友需要了解的东西
- 使用console进行性能测试
- 1亿条记录的MongoDB数据库随机查询性能测试
- eval的两组性能测试数据
- Java常用排序算法及性能测试集合
- Java中的StringBuilder性能测试
- Java中Map的遍历方法及性能测试
- python常用web框架简单性能测试结果分享(包含django、flask、bottle、tornado)
- nginx 和apache 性能测试对比
- 对性能测试的认识
- 有关性能测试结果的几点分析原则
- 性能测试工程师的面试题
- 转载:性能测试经验
- 测试过程控制----如何开展性能测试
- 性能测试, 压力测试 , 负载测试和 容量测试 的区别与联系
- 性能测试小Tips
- 软件测试LR通用性能分析流程