當前位置:
首頁 >
转:LruCache算法
發布時間:2025/3/17
28
豆豆
生活随笔
收集整理的這篇文章主要介紹了
转:LruCache算法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
1. 簡介
下面,將詳細介紹 LrhCache算法
2. LruCache算法
3. 實現原理
- LrhCache算法的算法核心 = LRU 算法 + LinkedHashMap數據結構
- 下面,我將先介紹LRU 算法 和 LinkedHashMap數據結構,最后再介紹LrhCache算法
3.1 LRU 算法
- 定義:Least Recently Used,即 近期最少使用算法
- 算法原理:當緩存滿時,優先淘汰 近期最少使用的緩存對象
采用 LRU 算法的緩存類型:內存緩存(LrhCache) 、 硬盤緩存(DisLruCache)
3.2 LinkedHashMap 介紹
- 數據結構 = 數組 +單鏈表 + 雙向鏈表
- 其中,雙向鏈表 實現了 存儲順序 = 訪問順序 / 插入順序
- 使得LinkedHashMap 中的<key,value>對 按照一定順序進行排列
- 通過 構造函數 指定LinkedHashMap中雙向鏈表的結構是訪問順序 or 插入順序
- 實例演示
當 accessOrder 參數設置為true時,存儲順序(遍歷順序) = 外部訪問順序
/** * 實例演示**/ // 1. accessOrder參數設置為true時LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>(0, 0.75f, true);// 2. 插入數據map.put(0, 0);map.put(1, 1);map.put(2, 2);map.put(3, 3);map.put(4, 4);map.put(5, 5);map.put(6, 6);// 3. 訪問數據map.get(1);map.get(2);// 遍歷獲取LinkedHashMap內的數據for (Map.Entry<Integer, Integer> entry : map.entrySet()) {System.out.println(entry.getKey() + ":" + entry.getValue());}/** * 測試結果**/ 0:03:34:45:56:61:12:2// 即實現了 最近訪問的對象 作為 最后輸出 // 該邏輯 = LrhCache緩存算法思想 // 可見LruCache的實現是利用了LinkedHashMap數據結構的實現原理 // 請看LruCache的構造方法public LruCache(int maxSize) {if (maxSize <= 0) {throw new IllegalArgumentException("maxSize <= 0");}this.maxSize = maxSize;this.map = new LinkedHashMap<K, V>(0, 0.75f, true);// 創建LinkedHashMap時傳入true。即采用了存儲順序 = 外界訪問順序 = 最近訪問的對象 作為 最后輸出}復制代碼3.3 LrhCache 算法原理
- 示意圖
4. 使用流程
/** * 使用流程(以加載圖片為例)**/ private LruCache<String, Bitmap> mMemoryCache; // 1. 獲得虛擬機能提供的最大內存// 注:超過該大小會拋出OutOfMemory的異常 final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); // 2. 設置LruCache緩存的大小 = 一般為當前進程可用容量的1/8// 注:單位 = Kb// 設置準則// a. 還剩余多少內存給你的activity或應用使用// b. 屏幕上需要一次性顯示多少張圖片和多少圖片在等待顯示// c. 手機的大小和密度是多少(密度越高的設備需要越大的 緩存)// d. 圖片的尺寸(決定了所占用的內存大小)// e. 圖片的訪問頻率(頻率高的在內存中一直保存)// f. 保存圖片的質量(不同像素的在不同情況下顯示)final int cacheSize = maxMemory / 8; // 3. 重寫sizeOf方法:計算緩存對象的大小(此處的緩存對象 = 圖片)mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { return bitmap.getByteCount() / 1024; // 此處返回的是緩存對象的緩存大小(單位 = Kb) ,而不是item的個數// 注:緩存的總容量和每個緩存對象的大小所用單位要一致// 此處除1024是為了讓緩存對象的大小單位 = Kb} }; // 4. 將需緩存的圖片 加入到緩存mMemoryCache.put(key, bitmap); // 5. 當 ImageView 加載圖片時,會先在LruCache中看有沒有緩存該圖片:若有,則直接獲取mMemoryCache.get(key); 復制代碼5. 實例講解
- 本實例以緩存圖片為實例講解
- 具體代碼
請看注釋
MainActivity.java
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"xmlns:app="http://schemas.android.com/apk/res-auto"android:focusableInTouchMode="true"android:orientation="vertical"><ImageViewandroid:id="@+id/image"android:layout_width="200dp"android:layout_height="200dp"android:layout_gravity="center"/><Buttonandroid:id="@+id/btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="10dp"android:text="點擊加載"android:layout_gravity="center"/></LinearLayout>復制代碼- 測試結果
第1次點擊加載圖片時,由于無緩存則從本地加載
第2次(以后)點擊加載圖片時,由于有緩存,所以直接從緩存中讀取
6. 源碼分析
此處主要分析 寫入緩存 & 獲取緩存 ,即put()、 get()
6.1 添加緩存:put()
- 源碼分析
至此,關于添加緩存:put()的源碼分析完畢。
6.2 獲取緩存:get()
- 作用:獲取緩存 & 更新隊列
- 當調用 get() 獲取緩存對象時,就代表訪問了1次該元素
- 訪問后將會更新隊列,使得整個隊列是按照 訪問順序 排列
- 示意圖如下
上述更新過程是在 get()中完成
- 源碼分析
至此,關于獲取緩存:get()的源碼分析完畢。
7. 總結
本文全面講解了內存緩存的相關知識,含LrhCache算法、原理等,下面是部分總結
- 原理
- 示意圖
- 源碼流程
轉載于:https://juejin.im/post/5bfe02426fb9a049ec6ac4c6
總結
以上是生活随笔為你收集整理的转:LruCache算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux监控脚本
- 下一篇: Nuxt --- 也来说说vue服务端渲