Android記憶體優化之記憶體快取
什麼是快取?
快取技術原理就是把使用者訪問的所有物件看作一個全集,經過演算法標記哪些是使用者經常訪問的物件,把這些物件放到一個集合裡,這個集合是全集一個子集,下一次使用者再訪問的時候會先從這個子集集合中查詢使用者要訪問的物件如果找到就直接返回這個物件,如果沒有找到則再去全集中查詢。當然了我這裡說的只是原理性的東西,快取是有很多演算法的,並且有的不止一級快取,這裡就不過多講了。
為什麼要用到快取?
有快取的話可以不必每次從源地址讀取檔案,既節省了時間也節省了流量。尤其是手機裝置,頻繁的訪問網路資源會消耗很多使用者的流量和電量,這是使用者不能忍受的,所以無論從哪個方面考慮應用程式都必須加上快取。
Android中的圖片快取有哪些?各有什麼特點?
Android裝置的圖片快取分兩種,一種是記憶體快取,圖片快取在裝置的記憶體中,一種是外部快取,圖片快取在磁碟上,磁碟可以是內部的儲存空間也可以是外部的sd卡。這兩種快取各有各的優點,記憶體快取優點是快,缺點是因為也是讀取到記憶體中所以也會消耗記憶體,所以不能太大,用的時候要考慮分配的空間,還有一個缺點是應用重啟後就會消失。外部快取的優點是可以長久儲存大量的資料(相比較記憶體快取而言),缺點就是慢。
記憶體快取:
在Android中官網推薦使用LruCache作為記憶體快取,LruCache實際上就是一個LinkedHashMap( 補充知識:LinkedHashMap是一個雙向迴圈列表,不支援執行緒安全,LruCache對它進行了封裝新增了執行緒安全操作),裡面儲存了一定數量的物件強引用,每次新增的新物件都是在連結串列的頭,當分配的空間用完的時候會把末尾的物件移除,移除的物件就可以被gc回收了。這裡需要注意一下LruCache的容量,這個容量既不能太大,會造成OOM,又不能太小,起不到快取的作用。google官網給出一下意見作為參考:
- 分配LruCache大小的時候考慮你的應用剩餘記憶體有多大;
- 一次螢幕顯示多少張圖片,有多少張圖片是快取起來準備顯示的;
- 考慮你的手機解析度和尺寸, 快取相同的圖片個數,dpi越大的手機需要的記憶體就會越大;
- 圖片解析度和畫素質量也決定了佔用記憶體的大小;
- 圖片訪問的頻繁程度是多少,是不是有一些圖片是經常訪問的?如果存在你可以考慮用多個·LruCache來做快取,按照訪問的頻率度分配到不同的LruCache中;
- 如何平衡一下圖片質量和數量,有些時候可以考慮快取低解析度的圖片,用到的時候再在後臺請求更高質量的圖片;
- 總之你分配的LruCache大小既不能太大,又不能太小,具體到應用中還要你綜合考慮。
下面的程式碼是使用LruCache的例子:
private LruCache<String, Bitmap> mMemoryCache;//宣告快取空間 final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);//獲取應用在系統中的最大記憶體分配 //分配1/8的應用記憶體作為快取空間 final int cacheSize = maxMemory / 8; mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { //重寫sizeOf方法,返回圖片的佔用位元組數而不是圖片的個數,每次新增圖片是會被呼叫 return bitmap.getByteCount() / 1024; } };
注意:有同學可能會問下面的程式碼:
intcacheSize=4*1024*1024;// 4MiB LruCachebitmapCache=newLruCache(cacheSize){ protectedintsizeOf(Stringkey,Bitmapvalue){ returnvalue.getByteCount(); } }
這兩個sizeOf的計算是不一樣的,這裡說明一下,這個方法重寫的目的是返回圖片佔用的快取空間而不是圖片的數目,並且這個數值的單位要和cacheSize一樣。
總結:
綜合上面的講解,在使用記憶體快取LruCache時你需要知道如下知識:
LruCache封裝了LinkedHashMap,提供了LRU(Least Recently Used 最近最少使用演算法)快取的功能;
LruCache通過trimToSize方法自動刪除最近最少訪問的鍵值對;
LruCache不允許空鍵值, LinkedHashMap允許;
LruCache執行緒安全, LinkedHashMap執行緒不安全;
繼承LruCache時,必須要複寫sizeOf方法,用於計算每個條目的大小。在put和get的時候會呼叫safeSizeOf(K key, V value),safeSizeOf(K key, V value)會呼叫 sizeOf (K key, V value),這個方法預設返回1。
另外推薦一款第三方的內測工具對APP進行全方面的檢測:http://www.ineice.com/
相關文章
- Android效能優化篇之記憶體優化--記憶體洩漏Android優化記憶體
- Android 效能優化之記憶體優化Android優化記憶體
- Android 效能優化之記憶體洩漏檢測以及記憶體優化(上)Android優化記憶體
- Android 效能優化之記憶體洩漏檢測以及記憶體優化(下)Android優化記憶體
- Android 效能優化之記憶體洩漏檢測以及記憶體優化(中)Android優化記憶體
- Android記憶體優化Android記憶體優化
- Android 記憶體優化Android記憶體優化
- Android記憶體優化(一):Java記憶體區域Android記憶體優化Java
- Android記憶體優化之圖片優化Android記憶體優化
- Android效能優化之記憶體篇Android優化記憶體
- CPU快取記憶體快取記憶體
- Android Note - 記憶體優化Android記憶體優化
- android 記憶體優化篇Android記憶體優化
- Android效能優化 - 記憶體優化Android優化記憶體
- Android APP 記憶體優化之圖片優化AndroidAPP記憶體優化
- Android學習之 記憶體管理機制與應用記憶體優化Android記憶體優化
- Android效能優化(三)之記憶體管理Android優化記憶體
- Android效能優化之記憶體洩漏Android優化記憶體
- Android應用優化之記憶體概念Android優化記憶體
- Android記憶體優化之static使用篇Android記憶體優化
- Android記憶體優化(三)避免可控的記憶體洩漏Android記憶體優化
- Android記憶體優化(五)詳解記憶體分析工具MATAndroid記憶體優化
- Android記憶體優化——記憶體洩露檢測分析方法Android優化記憶體洩露
- 關於redis記憶體分析,記憶體優化Redis記憶體優化
- DDD 和 記憶體快取記憶體快取
- iOS開發之記憶體與快取iOS記憶體快取
- Android 效能優化(四)之記憶體優化實戰Android優化記憶體
- 淺談Android記憶體優化Android記憶體優化
- Android記憶體優化全解析Android記憶體優化
- Android記憶體優化雜談Android記憶體優化
- android,記憶體優化詳解Android記憶體優化
- 記憶體使用總結篇 -- Android 記憶體優化第五彈記憶體Android優化
- 1.記憶體優化(一)記憶體洩漏記憶體優化
- Android記憶體快取LruCache原始碼解析Android記憶體快取原始碼
- 記憶體優化策略記憶體優化
- UIImage 記憶體優化UI記憶體優化
- PHP記憶體優化PHP記憶體優化
- 記憶體優化技巧記憶體優化