花絮:看到下面的代码就想起这么一个调侃:

  一个老程序员,功成名就,金盆洗手不在写代码后,决定练练书法。提笔思索良久后在纸上写下:Hello world!

/*********************************************************************************/

1 首先说下自动释放池的底层实现

它是通过以 AutoreleasePoolPage 为结点的双向链表来实现的。很类似栈的方式:对应push操作(底层是标记一个哨兵),这时相当于创建了一个自动释放池。当一个对象收到发送autorelease消息时,它被添加刚创建的自动释放池中,当自动释放池被回收时(对应pop操作),哨兵之后添加进来的对象从池中被删除, 并且会给它们发送release消息。则对象引用计数-1,如果为0则释放内存。很明显ARC相对于MRC,对象会延迟释放。

2 举例

有这么一段代码:largeNumber可以当做一个很大的数

for (int i =  ; i < largeNumber; i++) {
NSString *myStr = @"Hello world"; // 原谅我用Hello world
myStr = [myStr stringByAppendingString:[NSString stringWithFormat:@"-%05d-",i]];
}

  那么会有什么问题呢?

  如果largeNumber不大时没有问题,但是当它很大时问题非常严重!造成内存峰值。虽然ARC会自动释放内存,但是只有pop操作(完成一次runloop消息循环或@autoreleasepool {}结尾时)才会给池子里面的所有对象做一次release操作。

  当我们使用for循环创建很多个使用autorelease方式创建的NSString对象的时候,将所有的对象的释放权都交给了这个释放池,而这个释放池会等待完整的循环之后才有可能释放,因此就会使对象无法及时释放,堆积在内存造成内存峰值。

  代码应该这样修改:在循环内添加一个自动释放池,此时自动释放池就会处于当前线程的栈顶,那么每执行一次循环,就会新建一个自动释放池(push),循环结束进行一次(pop操作),那么添加在池子里面的对象就会被释放,则不会造成内存峰值。

for (int i =  ; i < largeNumber; i++) {
@autoreleasepool {
NSString *myStr = @"Hello world";
myStr = [myStr stringByAppendingString:[NSString stringWithFormat:@"-%05d-",i]];
}
}

最新文章

  1. 跟着百度学PHP[6]超级全局变量
  2. nfs文件系统挂载错误及解决方法
  3. jsp js action之间的传值
  4. 未能正确加载 ”Microsoft.VisualStudio.Editor.Implementation.EditorPackate“包错误解决方法
  5. [codevs2070]爱情之路
  6. 关于学习netty的两个完整服务器客户端范例
  7. 宣布 Azure Backup 支持备份 Windows Server 2008
  8. 图解三种APP的区别
  9. Swap Nodes in Pairs——LeetCode
  10. C语言初学 数组 打印菱形
  11. php php打乱数组二维数组、多维数组
  12. 【Java】【Fulme】Flume-NG源代码阅读之SpoolDirectorySource
  13. iOS开发者的管理工具-CocoaPods安装
  14. fiddler基本功能介绍
  15. Golang知识图谱
  16. HDU5543(SummerTrainingDay03-O DP)
  17. element-ui table中排序 取消表格默认排序问题
  18. Html的本质及在web中的作用
  19. jq 分页
  20. Object-c和Java中的代理

热门文章

  1. 这些HTML、CSS知识点,面试和平时开发都需要 No10-No11
  2. C#中方法的声明
  3. Ubuntu14.04安装postgresql9.4
  4. 使用 TOP 限制更新的数据
  5. 在_Layout模版中使用@Styles.Render()没有效果
  6. 【C#】VS2015开发环境的安装和配置(二)2016-08-03更新
  7. mysql,命令导入\导出表结构或数据
  8. volcanol_Linux_ 问题汇总系列_4_Thinkpad_E40_0578MDC_在Fedora 13 Linux(FC13)中如何安装无线网卡驱动
  9. Thinkphp各种方法知识图谱
  10. 在selenium2.0中使用selenium1.0的API