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 Note - 記憶體優化Android記憶體優化
- 淺談Android記憶體優化Android記憶體優化
- Android記憶體優化全解析Android記憶體優化
- CPU快取記憶體快取記憶體
- Android 是如何管理 App 記憶體的 — Android 記憶體優化第二彈AndroidAPP記憶體優化
- 關於redis記憶體分析,記憶體優化Redis記憶體優化
- 記憶體快取選型記憶體快取
- iOS開發之記憶體與快取iOS記憶體快取
- 1.記憶體優化(一)記憶體洩漏記憶體優化
- 多核cpu、cpu快取記憶體、快取一致性協議、快取行、記憶體快取記憶體協議
- android效能評測與優化-記憶體Android優化記憶體
- android記憶體管理機制與優化Android記憶體優化
- Linux 效能優化之 記憶體 篇Linux優化記憶體
- CPU快取和記憶體屏障快取記憶體
- docker部署redis快取記憶體DockerRedis快取記憶體
- 談談CPU快取記憶體快取記憶體
- django 快取表格到記憶體Django快取記憶體
- 直接記憶體和堆記憶體誰快記憶體
- Android 記憶體快取框架 LruCache 的原始碼分析Android記憶體快取框架原始碼
- 記憶體優化相關記憶體優化
- 實踐App記憶體優化:如何有序地做記憶體分析與優化APP記憶體優化
- MRAM快取記憶體的組成快取記憶體
- 高效能記憶體快取 ristretto記憶體快取
- 快取記憶體一致性協議MESI與記憶體屏障快取記憶體協議
- Android記憶體管理Android記憶體
- Android效能最佳化之記憶體洩露Android記憶體洩露
- Redis 記憶體優化神技,小記憶體儲存大資料Redis記憶體優化大資料
- cocos2d-x 優化(紋理渲染優化、資源快取、記憶體優化)優化快取記憶體
- 分析並優化 Android 應用記憶體佔用優化Android記憶體
- Android系統Bitmap記憶體分配原理與優化Android記憶體優化
- JNI記憶體管理及優化記憶體優化
- mariadb 記憶體佔用優化記憶體優化
- iOS圖片記憶體優化iOS記憶體優化
- App記憶體優化-實踐APP記憶體優化
- Redis-記憶體優化(一)Redis記憶體優化