android上的快取 快取演算法和快取框架

2021-09-06 19:16:44 字數 2909 閱讀 9114

快取是訪問資料的臨時地,因為取原始資料代價太大了,加了快取,可以取得快些。快取可以認為是原始資料的子集,它是從原始資料裡複製出來的,並且為了能被取回,被加上了標誌。

在android開發中,經常要訪問網路資料比如大量網路,如果每次需要同一張都去網路獲取,這代價顯然太大了。可以考慮設定本地檔案快取和記憶體 快取,儲存從網路取得的資料;本地檔案快取空間並非是無限大的,容量越大讀取效率越低,可設定乙個折中快取容量比如10m,如果快取已滿,我們需要採用合 適的替換策略換掉乙個已有的資料物件,並替之已乙個新的資料物件;記憶體快取作為最先被讀取的資料,應該儲存那些經常使用的資料物件,且記憶體容量有限,記憶體 快取的容量也應該限定。依照這樣的做法,取得乙個(總數為n)的流程應該是這樣的:

a.先在記憶體快取取(設儲存k個),若取到則返回(命中率為k/n,時間為ta),否則進行b;

b.在本地檔案快取(設能儲存m個)中取,若取到則返回並更新記憶體快取(命中率為(m-k)/n,時間為tb),否則進行c;

取一張的時間期望為:w = ta * (k/n) + tb * (m-k)/n + tc * (n-m)/n ,其中ta < tb < tc ,為使w代價小,即盡可能快的取得資料,我們應該提高記憶體快取的命中率和本地檔案快取的命中率,但兩者的容量都是有限制的,所以必須使用適合替換演算法來更 新兩者所儲存的物件。選擇合適的替換演算法是快取的難點所在。

least frequently used(lfu)

對每個快取物件計算他們被使用的頻率。把最不常用的快取物件換走。

least recently user(lru)

把最近最少使用的快取物件給換走。總是需要去了解在什麼時候,用了哪個快取物件。如果有人想要了解為什麼總能把最近最少使用的物件踢掉,是非常困難的。瀏 覽器就是使用了lru作為快取演算法。新的物件會被放在快取的頂部,當快取達到了容量極限,我會把底部的物件踢走,而技巧就是:我會把最新被訪問的快取對 象,放到快取池的頂部。

所以,經常被讀取的快取物件就會一直呆在快取池中。可以用資料或者鍊錶實現。其改進演算法有lru2 和 2q。

least recently used 2(lru2)

把被兩次訪問過的物件放入快取池,當快取池滿了之後,我會把有兩次最少使用的快取物件踢走。因為需要跟蹤物件2次,訪問負載就會隨著快取池的增加而增加。 如果用在大容量的快取池中,就會有問題。另外,還需跟蹤那麼不在快取的物件,因為他們還沒有被第二次讀取。這比lru好。

two queues(2q)

把被訪問的資料放到lru的快取中,如果該物件再一次被訪問,就把他轉移到第二個更大的lru快取。替換掉快取物件是為了保持第乙個快取池是第二個快取池 的1/3。當快取的訪問負載是固定的時候,把 lru 換成 lru2,就比增加快取的容量更好。這種機制使得該演算法比 lru2 更好。

adaptive replacement cache(arc)

這種演算法介於 lru 和 lfu 之間,由2個 lru 組成,第乙個,也就是 l1,包含的條目是最近只被使用過一次的,而第二個 lru,也就是l2,包含的是最近被使用過兩次的條目。因此,l1 放的是新的物件,而 l2 放的是常用的物件。該演算法是是效能最好的快取演算法之一,能夠自調,並且是低負載的。儲存著歷史物件,這樣,就可以記住那些被移除的物件,同時,也可以看到 被替換掉的物件是否可以留下,取而代之的是替換別的物件。該演算法記憶力很差,但是很快,適用性也強。

most recently used(mru)

該演算法與 lru是對應的。它替換掉最近最多被使用的物件,你一定會問為什麼。原因是,當一次訪問過來的時候,有些事情是無法**的,並且在快取系統中找出最少最近 使用的物件是一項時間複雜度非常高的運算。該演算法在資料庫記憶體快取中很見!每當一次快取記錄的使用,會把它放到棧的頂端。當棧滿了的時候,會把棧頂的物件 給換成新進來的物件!

first in first out(fifo)

這是乙個低負載的演算法,並且對快取物件的管理要求不高。通過乙個佇列去跟蹤所有的快取物件,最近最常用的快取物件放在後面,而更早的快取物件放在前面,當快取容量滿時,排在前面的快取物件會被踢走,然後把新的快取物件加進去。很快,但是不適用。

second chance

改進的fifo演算法,比 fifo 好的地方是改善了 fifo 的成本。一樣是在觀察佇列的前端,但是很fifo的立刻替換不同,它會檢查即將要被踢出的物件有沒有之前被使用過的標誌(1乙個bit表示),如果沒有被 使用過,就把他換出;否則,把這個標誌位清除,然後把這個快取物件當做新增快取物件加入佇列。你可以想象就這就像乙個環佇列。當再一次在隊頭碰到這個物件 時,由於它已經沒有標誌位,可以立刻就它換出。在速度上比fifo快。

clock

這是乙個更好的fifo,也比 second chance更好。因為它不會像second chance那樣把有標誌的快取物件放到佇列的尾部,但是也可以達到second chance的效果。它持有乙個裝有快取物件的環形列表,頭指標指向列表中最老的快取物件。當快取miss發生並且沒有新的快取空間時,它會根據指標指向 的快取物件的標誌位去決定應該怎麼做。如果標誌是0,直接用新的快取物件替代這個快取物件;如果標誌位是1,把頭指標遞增,然後重複這個過程,直到新的緩 存物件能夠被放入。

****** time-based

通過絕對的時間週期去失效那些快取物件。對於新增的物件,儲存特定的時間。很快,但不適用。

extended time-based expiration

通過相對時間去失效快取物件的;對於新增的快取物件,儲存特定的時間,比如是每5分鐘,每天的12點。

sliding time-based expiration

被管理的快取物件的生命起點是在這個快取的最後被訪問時間算起。很快,不太適用。

快取演算法主要考慮到了下面幾點:

成本。如果快取物件有不同的成本,應該把那些難以獲得的物件儲存下來。

容量。如果快取物件有不同的大小,應該把那些大的快取物件清除,這樣就可以讓更多的小快取物件進來了。

時間。一些快取還儲存著快取的過期時間。電腦會失效他們,因為他們已經過期了。

詳見  android上的乙個網路介面和快取框架enif 。

android上的快取 快取演算法和快取框架

快取是訪問資料的臨時地,因為取原始資料代價太大了,加了快取,可以取得快些。快取可以認為是原始資料的子集,它是從原始資料裡複製出來的,並且為了能被取回,被加上了標誌。在android開發中,經常要訪問網路資料比如大量網路,如果每次需要同一張都去網路獲取,這代價顯然太大了。可以考慮設定本地檔案快取和記憶...

刪除android快取

優先使用快取 webview.getsettings setcachemode websettings.load cache else network html view plain copy p 不使用快取 webview.getsettings setcachemode websettings....

android快取清理

獲取包名的應用快取 在生命週期方法oncreate中先呼叫一次getcachesize packagemanager pm getactivity getpackagemanager listinfos pm.getinstalledpackages 0 for packageinfo info i...