⑴ Glide ② — 緩存機制
閱讀本文需要先了解 Glide載入流程
首先介紹一下Glide中對圖片資源的封裝類: EngineResource
在活動緩存中,使用了一個map用來存放EngineResource對象,這里需要注意一個操作,就是這個EngineResource對象是用WeakReference包裹的,並且通過ReferenceQueue監聽了EngineResource的回收,在回收的時候會清理當前的活動緩存內容;
下面分析一下源碼是如果實現的:
首先,自定義一個WeakReference類,將key和resource傳進入(用於在WeakReference回收的時候釋放),傳入一個ReferenceQueue對象,用於監聽WeakReference回收
開啟一個子線程,在循環中監聽ReferenceQueue的返回值,通過這個返回值,判斷WeakReference有沒有回收,監聽的方法是ReferenceQueue.remove(),這是一個阻塞方法;所以要開子線程;
LruResourceCache繼承了LruCache類,關於LruCache類,簡單提一下,具體的可以參考我之前的博客 LruCache實現 ,LruCache繼承了LinkedHashMap,LinkedHashMap有一個特點,就get後的數據會移動到隊列,這就是Lru思想:固定一個容量,put的時候如果超過容量了,將最後一個節點刪除,get的時候將get的這個節點移動到隊列的頭部;
onItemEvicted()方法是LruCache的一個空方法,調用的時機是在put的時候判斷是否超過容量,如果超過容量了,就淘汰最後一個節點,並調用這個方法;
活動緩存和內存緩存都是緩存在內存中的,活動緩存緩存的是正在使用的圖片資源,當圖片不使用時會放到內存緩存中,提出活動緩存的目的:單一的內存緩存由於Lru的淘汰機制會導致圖片載入不穩定
首先介紹一個磁碟緩存方案DiskLruCache(非Google官方編寫,但獲得官方認證),關於這個磁碟緩存方案的理解可以看郭林的這片文章:
Android DiskLruCache完全解析,硬碟緩存的最佳方案
從上一篇文章知道,Glide載入操作是通過 Engine 來驅動的
Engine的load()中,首先嘗試從 活動緩存 和 內存緩存 獲取緩存,如果沒有緩存再啟動EngineJob和DecodeJob; 上面介紹了緩存的獲取,下面看一下緩存的存放,肯定是在獲取到圖片後的回調中存放的
在DecodeJob獲取到圖片數據後,會回調很多介面,在回調中會將其放入 活動緩存 ,當圖片不在使用的時候,就會放入內存緩存,根據上面介紹的活動緩存規則,當 EngineResource 計數為0時就應該放入內存緩存;
當資源引用為0,回調onResourceReleased(),從活動緩存移除,放入內存緩存;
上面介紹了活動緩存和內存緩存的存放和獲取,下面看一看磁碟緩存的存取;
還記得 DataFetcherGenerator 介面嗎?這個介面是DecodeJob用於獲取數據的,有三個具體的實現:
我們在上一篇具體介紹的是網路文件的獲取,這里的磁碟緩存使用的就是 DataCacheGenerator(緩存文件) 這個Generator了
上篇文章知道DecodeJob是一個Runnable任務,在run()會調用runWrapped(),在runWrapped()中會做三種事情:
在runWrapped()的解碼操作中會執行decode(),在decode()中,會disk put操作;
Glide的磁碟緩存是基於DiskLruCache 實現的,Glide直接使用的是DiskLruCacheWrapper對象對DiskLruCache 的封裝;
⑵ 內存、緩存、快閃記憶體的定義和具體作用!
緩存是指可以進行高速數據交換的存儲器,它先於內存與CPU交換數據,因此速度很快
緩存(Cache memory)是硬碟控制器上的一塊內存晶元,具有極快的存取速度,它是硬碟內部存儲和外界介面之間的緩沖器。由於硬碟的內部數據傳輸速度和外界介面傳輸速度不同,緩存在其中起到一個緩沖的作用。緩存的大小與速度是直接關繫到硬碟的傳輸速度的重要因素,能夠大幅度地提高硬碟整體性能。當硬碟存取零碎數據時需要不斷地在硬碟與內存之間交換數據,如果有大緩存,則可以將那些零碎數據暫存在緩存中,減小外系統的負荷,也提高了數據的傳輸速度。
硬碟的緩存主要起三種作用:一是預讀取。當硬碟受到CPU指令控制開始讀取數據時,硬碟上的控制晶元會控制磁頭把正在讀取的簇的下一個或者幾個簇中的數據讀到緩存中(由於硬碟上數據存儲時是比較連續的,所以讀取命中率較高),當需要讀取下一個或者幾個簇中的數據的時候,硬碟則不需要再次讀取數據,直接把緩存中的數據傳輸到內存中就可以了,由於緩存的速度遠遠高於磁頭讀寫的速度,所以能夠達到明顯改善性能的目的;二是對寫入動作進行緩存。當硬碟接到寫入數據的指令之後,並不會馬上將數據寫入到碟片上,而是先暫時存儲在緩存里,然後發送一個「數據已寫入」的信號給系統,這時系統就會認為數據已經寫入,並繼續執行下面的工作,而硬碟則在空閑(不進行讀取或寫入的時候)時再將緩存中的數據寫入到碟片上。雖然對於寫入數據的性能有一定提升,但也不可避免地帶來了安全隱患——如果數據還在緩存里的時候突然掉電,那麼這些數據就會丟失。對於這個問題,硬碟廠商們自然也有解決辦法:掉電時,磁頭會藉助慣性將緩存中的數據寫入零磁軌以外的暫存區域,等到下次啟動時再將這些數據寫入目的地;第三個作用就是臨時存儲最近訪問過的數據。有時候,某些數據是會經常需要訪問的,硬碟內部的緩存會將讀取比較頻繁的一些數據存儲在緩存中,再次讀取時就可以直接從緩存中直接傳輸
計算機業界,內存這個名詞被廣泛用來稱呼 RAM( 隨機存取內存 ) 計算機使用隨機存取內存來儲存執行作業所須的暫時指令以及數據以使計算機的 CPU( 中央處理器 ) 能夠更快速讀取儲存在內存的指令及數據。
例來說,當處理器載入一個應用程序 - 例如文字處理或頁面編輯程序 - 到內存使應用程序能以最快速及最高效率的方式執行。以實用價值而言,將程序載入內存能夠確保計算機能以更短的時間來執行作業而使工作能夠更迅速地完成
內存與儲存的差別
大多數人常將內存 (Memory) 與儲存空間 (Storage) 兩個名字混為一談 , 尤其是在談到兩者的容量的時候 內存是指 (Memory) 計算機中所安裝的隨機存取內存的容量而儲存 (Storage) 是指計算機內硬碟的容量 為了避免混淆 , 我們將計算機比喻為一個有辦公桌與檔案櫃的辦公室。想像一下這個辦公桌與檔案櫃的比喻。想像每次想要閱讀一份文件或數據夾都必須從檔案櫃中找尋的情形,這會大幅減低工作執行的速度 , 更別說會把人逼瘋了。如果有足夠的辦公桌空間 ( 如內存 ), 便能夠將所需要的檔攤開 , 並能立即一眼就能找出所需的信息。
另一個內存與儲存最重要的差別在於 : 儲存於硬碟中的信息在關機後能夠保持完整,但任何儲存在內存中的數據在計算機關機後便會全部流失。就像在辦公室的比喻中 , 任何在下班時間後被遺留在桌上的檔或檔案都會全部被丟棄一樣
增加計算機系統中的內存能夠增加計算機的效能表現是眾所皆知的。如果內存沒有足夠的空間 , 計算機就必須建立一個虛擬內存檔案。在這個過程中 , 中央處理器在硬碟中保留一個空間來代替額外的隨機存取內存 這個稱為 」 Swapping」 的程序減低系統的速度一般的計算機從內存存取大約需要 200ns( 奈秒 ), 但從硬碟存取則需要 12,000,000ns 具體來說就等於花四個半月的時間來完成三分半中就能完成的工作 !
快閃記憶體存儲器是保留實力,即使其內容刪除.
Flash memory is a form of EAPROM (Electrically Alterable Programmable Read-Only Memory).快閃記憶體是一種eaprom(可變電可編程只讀存儲器).
Each bit of data in a flash memory device is stored in a transistor called a floating gate.每一個比特的數據儲存在快閃記憶裝置稱為浮柵晶體管. The floating gate can only be accessed though another transistor, the control gate.浮動門雖然只能進入另一個晶體管,控制閘門.
The process the control gate uses to access the floating gate is a field emission phenomenon known as Fowler-Nordheim tunneling.利用過程式控制制閘門進入浮柵是場發射現象稱為Fowler-Nordheim隧. Tunneling allows voltage to flow from the control gate to the floating gate through the dielectric layer of oxide which separates them.允許從隧道流電壓控制的浮動柵柵絕緣層氧化物通過分隔他們.
⑶ java如何將從資料庫取出的數據預先存入到內存
你要實現的這個可能跟SpringMvc的關系不是很大。
你要達到的目的其實就是在jvm啟動的時候把資料庫數據載入一份到內存,一個靜態變數和一個靜態初始化塊就可以搞定你的問題,這兩者都是在類載入的時候初始化一次,像前面回答的一樣,你可以用一個HashMap搞定。稍微具體來說,一個靜態變數
public static final Map<key,value> cache=new HashMap<key,value>()
static {
cache=請求資料庫操作
}
key你自己加,String還是int都行,value是你資料庫的結構,可以寫個實體。獲取的時候直接cache.get(key)就可以了。