iOS开发——处理1000张图片的内存优化

一、项目需求

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

 

二、内存分析,非优化

我在测试项目中,重复加载了一张图片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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/395678.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jquery ui php,php – 打开带有动态内容的jQuery UI对话框

我有一个关于jQuery UI对话框的问题,并显示数据库中的动态内容.所以我得到了一个web应用程序,我还需要创建一个管理模块来管理所有用户和其他信息.我创建了一个页面,显示列表中的所有用户,在每一行中我也创建了一个编辑按钮.我想这样做,当你按下用户的编辑按钮时,会打开一个对话…

linux shell的单行多行注释

1.单行注释&#xff0c;使用符号# echo "123456"echo "test"#echo "comment“ 2. 多行注释 &#xff08;1&#xff09;使用 :<<! &#xff01; filenametest.txt :<<! fileContentcat $filenamei0 for line in $fileContent dofileList[…

MapReduce Input Split 输入分/切片

MapReduce Input Split&#xff08;输入分/切片&#xff09;详解 public static long getMaxSplitSize(JobContext context) { return context.getConfiguration().getLong(SPLIT_MAXSIZE, Long.MAX_VALUE); } 如果没有设置这maxsize默认是Long.MAX_VALUE public static long …

win7无损扩大c盘空间_无损网络导航的空间模型

win7无损扩大c盘空间by Patryk Adaś通过PatrykAdaś 无损网络导航的空间模型 (A Spacial Model for Lossless Web Navigation) In my last post I described the concept of navigation trails as an evolution of the standard tabbed browsing model.在我的上一篇文章中&am…

php访问者信息,如何通过PHP检索访问者的ISP?

我试图纠正拉姆库马尔的答案,但每当我编辑他们的帖子,我将被暂时禁止,我的修改被忽略。(至于为什么,我不知道,这是我第一次也是唯一一次在这个网站上编辑。)由于网站更改和管理员执行基本的bot检查(检查标题),他的代码不再工作:$IP $_SERVER[REMOTE_ADDR];$User_Agent Mozill…

从《在小吃店遇见凯恩斯》初识经济

最近在看《在小吃店遇见凯恩斯》这本书&#xff0c;算是对经济和经济学的初步认识。 那些概念 1. 经济与经济学 经济&#xff1a;经世济民&#xff0c;经营国家、救赎百姓&#xff0c;发展国家经济进步、促成人人致富。 经济学&#xff1a;研究发展国家经济进步、促成人人致富的…

2pc 3pc_在1990年代如何宣传PC

2pc 3pcby Ilya Pestov通过伊利亚佩斯托夫(Ilya Pestov) 在1990年代如何宣传PC (How PCs were advertised in the 1990s) Today, hard drives are boring. You can buy a terabyte hard drive for $50. But back in the day, people would get excited when they saw ads anno…

WPF自定义空心文字

WPF自定义空心文字 原文:WPF自定义空心文字首先创建一个自定义控件&#xff0c;继承自FrameworkElement&#xff0c;“Generic.xaml”中可以不添加样式。 要自定义空心文字&#xff0c;要用到绘制格式化文本FormattedText类。FormattedText对象提供的文本格式设置功能比WPF提供…

php默认日志位置,Laravel 修改默认日志文件名称和位置的例子

修改默认日志位置我们平常的开发中可能一直把laravel的日志文件放在默认位置不会有什么影响&#xff0c;但如果我们的项目上线时是全量部署&#xff0c;每次部署都是git中最新的代码&#xff0c;那这个时候每次都会清空我们的日志&#xff0c;显示这不是我们所期望的&#xff0…

【转】UITableView详解(UITableViewCell

原文网址&#xff1a;http://www.kancloud.cn/digest/ios-1/107420 上一节中,我们定义的cell比较单一,只是单调的输入文本和插入图片,但是在实际开发中,有的cell上面有按钮,有的cell上面有滑动控件,有的cell上面有开关选项等等,具体参加下面2个图的对比: 我们可以通过…

Android 最简单的MVP案例;

随手撸个发出来&#xff1a; V&#xff1a;界面层 //界面层需要实现P.View方法&#xff0c;然后重写P.View中的方法&#xff1b;M层给的数据就在这些个方法的参数中&#xff1b; // 还要获取到P.Provide的实例&#xff0c;使用P.Provide去调用M层的方法&#xff1b; public cla…

c++编码风格指南_100%正确编码样式指南

c编码风格指南Tabs or spaces? Curly brace on the same line or a new line? 80 character width or 120?制表符或空格&#xff1f; 在同一行或新行上大括号&#xff1f; 80个字符的宽度还是120个字符&#xff1f; Coders love to argue about this kind of stuff. The ta…

Netty源码注释翻译-Channel类

定义为一个通往网络socket或者一个由I/O读写能力的组件。 通道提供&#xff1a; 1&#xff0c;通道的当前状态&#xff0c;打开&#xff1f;已连接&#xff1f; 2&#xff0c;跟通道关联的配置信息ChannelConfig&#xff0c;包括buffer大小等。 3&#xff0c;通道支持的I/O操作…

Today is weekend不是应该一定会输出吗

判断语句 If…else块&#xff0c;请看下面这个例子&#xff1a; <%! int day 3; %>                       //声明变量感叹号 <html> <head><title>IF...ELSE Example</title></head> <body> <% if (day …

时间模块和时间工具

一、time模块 三种格式 时间戳时间&#xff1a;浮点数 单位为秒 时间戳起始时间&#xff1a; 1970.1.1 0:0:0 英国伦敦时间 1970.1.1 8:0:0 我国(东8区) 结构化时间&#xff1a;元组(struct_time) 格式化时间&#xff1a;str数据类型的 1、常用方法 import timetime.sleep(secs…

redux扩展工具_用鸭子扩展您的Redux App

redux扩展工具How does your front-end application scale? How do you make sure that the code you’re writing is maintainable 6 months from now?您的前端应用程序如何扩展&#xff1f; 您如何确定您正在编写的代码从现在起6个月内可维护&#xff1f; Redux took the …

mac下源码安装redis

转载&#xff1a;http://www.jianshu.com/p/6b5eca8d908b 下载安装包 redis-3.0.7.tar.gz 官网地址&#xff1a;http://redis.io/download 解压&#xff1a;tar -zvxf redis-3.0.7.tar.gz 将解压后的文件夹放到 /usr/local目录下 编译测试:接下来在终端中切换到/usr/local/red…

代码扫描工具测试覆盖率工具

测试覆盖率工具转载于:https://www.cnblogs.com/vivian-test/p/5398289.html

php splqueue 5.5安装,解析PHP标准库SPL数据结构

SPL提供了双向链表、堆栈、队列、堆、降序堆、升序堆、优先级队列、定长数组、对象容器SplQueue 队列类进出异端&#xff0c;先进先出<?php $obj new SplQueue();//插入一个节点到top位置$obj->enqueue(1);$obj->enqueue(2);$obj->enqueue(3);/**SplQueue Object…

Beta阶段敏捷冲刺总结

设想和目标 1. 我们的软件要解决什么问题&#xff1f;是否定义得很清楚&#xff1f;是否对典型用户和典型场景有清晰的描述&#xff1f; 在最开始的时候我们就是为了解决集美大学计算机工程学院网页没有搜索引擎的问题。因为没有搜索引擎&#xff0c;在搜索内容时需要根据查找信…