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.pswp.cn/news/395678.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/395678.shtml
英文地址,請注明出處:http://en.pswp.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;在搜索內容時需要根據查找信…