一、项目需求

在实际项目中,用户在上传图片时,有时会一次性上传大量的图片。在上传图片前,我们要进行一系列操作,比如:旋转图片为正确方向,压缩图片等,这些操作需要将图片加载到内存中,下面对内存的使用做详细分析.

二、内存分析,非优化

我在测试项目中,重复加载了一张图片1000次,首先加载图片到内存,然后进行压缩操作,释放内存

for (int i = 0; i <= 1000; i ++) { //1.首先我们获取到需要处理的图片资源的路径 NSString *filePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"PNG"]; //2.将图片加载到内存中,我们使用了alloc关键字,在使用完后,可以手动快速释放掉内存 UIImage *image = [[UIImage alloc] initWithContentsOfFile:filePath]; //3.这一步我们将图片进行了压缩,并得到一个autorelease类型实例 UIImage *image2 = [image imageByScalingAndCroppingForSize:CGSizeMake(480, 320)]; //4.释放掉2步骤的内存 [image release]; }

上面的代码看起来没有任何问题,可以说是一种标准的代码写法,在每一步骤中都对内存做了小心的处理,我们来看一下,实际的内存使用情况:

在上图中可以看到,我们的操作在没有任何问题的情况下,在加载大量图片时,还是会造成内存的剧减 

可以看到自动释放内存时,图片占用的内存并没有立即释放掉

这些资源没有立即释放的资源,占用了宝贵的内存资源,最终使程序被kill

三优化后的内存使用

上面程序被kill,是因为程序的内存使用问题,在上面的代码中,我们每一步都对内存做了非常小心的处理,但是在加载大量的图片时,还是会出现问题。其根本原因就是autorelease惹的祸,autorelease自动释放内存,并不会立即把内存释放掉,而是要等到下一个事件周期才会释放掉。问题是一些资源我们不得不使用autorelease类型,比如作为函数的返回值,而且系统api及项目是的大部分也都是这么做的,如果全都依靠我们手动释放很容易造成内存泄漏。

for (int i = 0; i <= 1000; i ++) { //创建一个自动释放池 NSAutoreleasePool *pool = [NSAutoreleasePool new]; NSString *filePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"PNG"]; UIImage *image = [[UIImage alloc] initWithContentsOfFile:filePath]; UIImage *image2 = [image imageByScalingAndCroppingForSize:CGSizeMake(480, 320)]; [image release]; //将自动释放池内存释放,它会同时释放掉上面代码中产生的临时变量image2 [pool drain]; }

优化后的,内存使用情况

可用内存不再明显的减少

CGImage及UIImage的数据由原来的220多减少到6-7个

可以看到使用了 NSAutoreleasePool后,加载大量图片的时候内存也不会出现问题

四、自动释放池概述

(1)自动释放池被置于一个堆栈中,虽然它们通常被称为被“嵌套”的。当您创建一个新的自动释放池时,它被添加到堆栈的顶部。当自动释放池被回收时,它们从堆栈中被删除。当一个对象收到送autorelease消息时,它被添加到当前线程的目前处于栈顶的自动释放池中。你不能向自动释放池发送autorelease或retain消息。Application Kit会在一个事件周期(或事件循环迭代)的开端—比如鼠标按下事件—自动创建一个自动释放池,并且在事件周期的结尾释放它,因此您的代码通常不必关心。 有三种情况您应该使用您自己的自动释放池:

  • 如果您正在编写一个不是基于Application Kit的程序,比如命令行工具,则没有对自动释放池的内置支持;您必须自己创建它们。

  • 如果您生成了一个从属线程,则一旦该线程开始执行,您必须立即创建您自己的自动释放池;否则,您将会泄漏对象。

  • 如果您编写了一个循环,其中创建了许多临时对象,您可以在循环内部创建一个自动释放池,以便在下次迭代之前销毁这些
     对象。这可以帮助减少应用程序的最大内存占用量。

(2) release和drain之间的差异

在引用计数环境下,release和drain一样,会直接自动释放池l对象。

在GC(垃圾回收)环境下,release是一个no-op(空操作),drain会触发垃圾回收(如果自上次垃圾回收以来分配的内存大于当前的阈值)。

通常情况下,您都应该使用drain而不是使用release来销毁自动释放池。

-drain方法只适用于Mac OS X10.4(Tiger)及更高版本。

在OS X Mountain Lion v10.8操作系统下,GC(垃圾回收)将被废弃,ARC(Automatic Reference Counting自动引用计数)为推荐的替代技术。

转载于:https://www.cnblogs.com/qinxiaoguang/p/5606095.html

iOS开发——处理1000张图片的内存优化相关推荐

  1. iOS高级教程:处理1000张图片的内存优化

    博文转载至 http://blog.csdn.net/trandy/article/details/8446220 转载请保留以下原文链接: http://my.oschina.net/taptale ...

  2. iOS开发UI篇—UITableviewcell的性能优化和缓存机制

    iOS开发UI篇-UITableviewcell的性能问题 一.UITableviewcell的一些介绍 UITableView的每一行都是一个UITableViewCell,通过dataSource ...

  3. ios加载本地html懒加载图片方案,IOS开发中加载大量网络图片优化方法

    IOS开发中加载大量网络图片如何优化 1.概述 在IOS下通过URL读一张网络图片并不像其他编程语言那样可以直接把图片路径放到图片路径的位置就ok,而是需要我们通过一段类似流的方式去加载网络图片,接着 ...

  4. iOS开发学无止境 - 异步图片加载优化与常用开源库分析

    作者:罗轩(@luoyibu) 网址:http://www.jianshu.com/p/3b2c95e1404f 1. 网络图片显示大体步骤:   下载图片 图片处理(裁剪,边框等) 写入磁盘 从磁盘 ...

  5. iOS开发之加载大量网络图片优化

    2019独角兽企业重金招聘Python工程师标准>>> 1.概述 在IOS下通过URL读一张网络图片并不像其他编程语言那样可以直接把图片路径放到图片路径的位置就ok,而是需要我们通过 ...

  6. android 图库 imgcache.idx,iOS开发 - 关于列表图片渲染内存暴增问题

    关于列表图片渲染内存暴增问题 - (void)viewDidLoad { [super viewDidLoad]; [SDImageCache sharedImageCache].config.sho ...

  7. 文顶顶iOS开发博客链接整理及部分项目源代码下载

    网上的iOS开发的教程很多,但是像cnblogs博主文顶顶的博客这样内容图文并茂,代码齐全,示例经典,原理也有阐述,覆盖面宽广,自成系统的系列教程却很难找.如果你是初学者,在学习了斯坦福iOS7公开课 ...

  8. iOS 与OS X多线程和内存管理 笔记 ARC与所有权修饰符

    注:本文为笔记形式,所以很多都是摘抄的.<<iOS 与OS X多线程和内存管理>>书中写的很棒,简单易懂,建议各位看官自己去看看. ####ARC和MRC 前一篇主要是MRC环 ...

  9. 【 iOS 应用开发 】 UIKit 控件 ( 代码生成控件 | UIView 属性方法 | Storyboard | Bundle | Property List | 动画 | 图片内存优化 )

    文章目录 一. 代码生成控件 1. 创建设置项目 ( 1 ) 创建项目 ( ① 选择 Create a new Xcode project | ② 创建 Single View Application ...

最新文章

  1. yii框架相关知识(转)
  2. 【C++】cannot access private member declared in class 'Box'
  3. CVPR 2022 3月7日论文速递(17 篇打包下载)涵盖 3D 目标检测、医学影像、图像去模糊、车道线检测等方向
  4. C语言数组元素总和最大的连续子序列的算法(附完整源码)
  5. 包治百病 | 如何将一个.NET Core类库发布到NuGet
  6. Maven硒测试自动化教程
  7. mysql导出表结构 创建_mysql如何导出表结构为文本文件
  8. Google编程之夏入围项目公布
  9. php dm,DM_cp.php
  10. win32开发(调试)
  11. 远程桌面未知的用户名_电脑在远程桌面连接时出现用户名密码错误该怎么办?...
  12. java笔记--关于int和byte[]的转换
  13. c++ builder 2010论坛_CHiF中国血液创新论坛 | 领域大咖带您开启CLL的个体化治疗之门...
  14. [4G5G专题-81]:流程 - 4G LTE 小区切换流程大全
  15. 【考研复习】《操作系统原理》孟庆昌等编著课后习题+答案——第四章
  16. AngularJS - uib-datepicker-popup - 日期控件
  17. 拼多多优惠券bug造成千万损失引发的优惠券安全思考
  18. 相信我,我们离成为废物阶级不远了!
  19. 深圳摇号验证码一输完就变的解决办法
  20. C DoEvents

热门文章

  1. php 如何宏定义,php – 在html中实现宏定义的方法
  2. python软件是哪个国家的品牌_有哪些好用的软件被国人误认为是外国研发的?
  3. php 批量更新死锁,php – 在尝试获取锁定时,哪个查询导致死锁;尝试重新启动事务...
  4. coreos 安装mysql_CoreOS 在 PC 上快速安装方法指南
  5. 操作系统上机作业--实现shell(1)(多进程)
  6. c++ socket学习(1.1)
  7. python 示例_带有示例的Python date isocalendar()方法
  8. c语言输出最大素数,for语句计算输出10000以内最大素数怎么搞最简单??各位大神们...
  9. php的文件包含总结 include require include_once require_once
  10. POJ 3660 Cow Contest(传递闭包floyed算法)