iOS內(nèi)存分析上-圖片加載內(nèi)存分析
簡介
對于大多數(shù)App來說魁巩,內(nèi)存占用主要就是圖片。本文將從實用的角度分析于游,iOS圖片的內(nèi)存占用窖壕、測量忧勿、優(yōu)化等。
iOS內(nèi)存-有什么影響
在移動操作系統(tǒng)設(shè)備中瞻讽,是不能像PC一樣進行內(nèi)存swap的鸳吸,而隨著用戶的實用,打開的應(yīng)用越來越多速勇,應(yīng)用使用的內(nèi)存也越來越多晌砾。當占用的內(nèi)存達到某個臨界值時,iOS系統(tǒng)會嘗試按照優(yōu)先級逐個kill掉應(yīng)用程序烦磁,以維護系統(tǒng)的流暢和穩(wěn)定养匈。
當iOS系統(tǒng)在清理內(nèi)存過程中,優(yōu)先級到了前臺正在運行的應(yīng)用程序都伪,那么就會出現(xiàn)前臺應(yīng)用程序閃退的現(xiàn)象呕乎,也就是通常所說的OOM。
iOS內(nèi)存-關(guān)注什么
實際上陨晶,對于iOS系統(tǒng)內(nèi)存猬仁,根據(jù)劃分的方法方式,有很多內(nèi)存種類先誉,比較常見的有clean memory, dirty memory湿刽,有virtual memory, resident memory,等等褐耳。那么這么多的內(nèi)存诈闺,重點要關(guān)注什么呢?
For the purposes of this guide, Persistent Bytes for All Heap & Anonymous VM represents your app's memory footprint.
這句話來自蘋果的官方技術(shù)文檔铃芦,翻譯過來就是买雾,在內(nèi)存優(yōu)化中,需要關(guān)注的memory footprint就是“Persistent Bytes for All Heap & Anonymous VM”杨帽。也就是下圖中instruments-Allocation中的①漓穿。至于提到的memory footprint,可以參考wiki注盈。
也就是說晃危,iOS內(nèi)存優(yōu)化看“memory footprint”,“memory footprint”優(yōu)化看“Persistent Bytes for All Heap & Anonymous VM”
iOS內(nèi)存-圖片內(nèi)存怎么算
先打一個比喻,我們平時為了傳輸方便僚饭,往往會對文件進行壓縮震叮,得到一個.rar或者.zip的壓縮包,當我們要閱讀文件時鳍鸵,需要先解壓壓縮包苇瓣,得到.doc或者.txt等文檔,然后再打開閱讀偿乖。
類似的击罪,我們平時看到的.jpg,.png贪薪,就是上面所說的壓縮包媳禁,這個文件是不能直接上屏渲染的,需要先解壓縮画切,然后才能在上屏竣稽。而我們平時無感知,直接打開文件就能看霍弹,是因為解碼渲染很快毫别,在你點擊的時候就完成了解碼+渲染的操作了,類似.zip壓縮包也可以不解壓直接預覽一樣典格。
那么顯而易見岛宦,我們看到的磁盤上的圖片和最終渲染出來的圖片是不同的,那么圖片實際加載渲染時的內(nèi)存要怎么算呢钝计。在iOS中可以通過以下公式快速計算。其中4是每個像素占用的byte齐佳,在iOS中固定為4(至少目前為止是的)私恬,Android中需要根據(jù)實際的調(diào)整,一般也是4炼吴。
內(nèi)存大小=像素寬*像素高*4
iOS內(nèi)存-圖片內(nèi)存怎么取
如果要進行圖片內(nèi)存的優(yōu)化本鸣,首先得保證能監(jiān)測到圖片的內(nèi)存大小。圖片內(nèi)存的測量硅蹦,各家有各家的方案荣德,但是總的來說,都是在某個或多個圖片加載的入口童芹,進行侵入或非侵入AOP涮瞻,進行相關(guān)的計算。
這里推薦一個方法假褪,實用NSHashtable署咽,弱引用持有對象。將圖片的對象放到這個弱引用的hash表中,可以實時查看當前仍存活的所有圖片對象宁否,并據(jù)此計算圖片占用的內(nèi)存窒升。
iOS中UIImage內(nèi)存占用:
UIImage內(nèi)存占用大小:image.size.width*image.size.height*image.scale
iOS內(nèi)存-圖片內(nèi)存優(yōu)化
iOS圖片內(nèi)存優(yōu)化慕匠,大的方向就是:
少用饱须,勤釋放
就是在頁面中同時加載的圖片數(shù)量要少,單張圖片的大小要小台谊,圖片占用的內(nèi)存要勤釋放蓉媳,用CPU換內(nèi)存。
一個典型的優(yōu)化就是青伤,UITableView中督怜,cell的reuse。單個cell的高度推薦小于1屏狠角,cell要能夠重用号杠,列表滾動時,cell中的圖片按需加載和釋放丰歌。能夠做到這些姨蟋,一般的圖片內(nèi)存問題都能夠很好的解決。
iOS內(nèi)存-圖片按需加載
目前流行的圖片加載立帖,都會選取CDN眼溶,將原圖進行初步的壓縮,然后加載晓勇,但是這個更多的考慮的是服務(wù)的的性能堂飞,負載均衡等等,客戶端的收益基本就只有流量一條绑咱〈律福客戶端內(nèi)存的優(yōu)化微乎其微。
根據(jù)上面說的圖片內(nèi)存解釋描融,我們知道圖片內(nèi)存暴漲就是在對其解壓縮時铝噩。如果看過iOS最流行的圖片加載框架SDWebImage,和騰訊開源圖片框架LKImageKit窿克,可以發(fā)現(xiàn)LKImageKit有一個很精細的圖片加載優(yōu)化骏庸,就是在圖片解碼時,根據(jù)加載圖片的view的frame年叮,進行解碼具被。這樣就避免了一個很小的view,加載一張很大的圖片只损,消耗大量內(nèi)存的情況硬猫。
在SDWebImage中,要實現(xiàn)這個feature會有點麻煩。需要將上層調(diào)用的frame透傳到最下面的解碼部分啸蜜,且需要做一些錯誤校驗坑雅。
此外,需要注意的是衬横,壓縮率比較高的圖片裹粤,在進行這種二次壓縮時,壓縮后的圖片有可能會有很嚴重的失真蜂林。