当前位置:网站首页>Android caching mechanism lrucache
Android caching mechanism lrucache
2022-06-09 17:17:00 【Mengfangfang】
1.Android Cache policy in
Generally speaking , Cache policy mainly includes the addition of cache 、 Get and delete these three types of operations . Adding and getting caches is easy to understand , Why delete the cache ? This is because whether it is memory cache or hard disk cache , Their cache size is limited . When the cache is full , If you want to add a cache, you need to delete some old cache to add a new cache .
therefore LRU(Least Recently Used) The caching algorithm came into being ,LRU Is the least recently used algorithm , Its core idea is when the cache is full , Will give priority to those cache objects that have been used least recently . About Android Third level cache of , The main ones are memory cache and hard disk cache . The implementation of these two caching mechanisms is applied to LruCache Algorithm .
2.LruCache
LruCache yes Android 3.1 Provides a cache class , So in Android Can be used directly in LruCache Implement memory cache . Hard disk cache DisLruCache Currently in Android Is not Android SDK Part of , but Android Official documents recommend using this algorithm to realize hard disk caching .
LruCache It's a generic class , The main principle of the algorithm is to store the recently used objects in LinkedHashMap in . When the cache is full , Remove the least recently used object from memory , And provides get and put Method to get and add the cache .
LruCache Is very simple to use , Take the picture cache as an example :
// Get the maximum memory allocated by the system to each application
int maxMemory=(int)(Runtime.getRuntime().ma xMemory()/1024);
int cacheSize=maxMemory/8;
private LruCache<String, Bitmap> mMemoryCache;
// to LruCache Distribute 1/8 Maximum memory
mMemoryCache = new LruCache<String, Bitmap>(mCacheSize){
// Override the method , To measure Bitmap Size
@Override
protected int sizeOf(String key, Bitmap value){
return value.getRowBytes() * value.getHeight()/1024;
}
};
① Set up LruCache Cache size , Generally, it is... Of the available capacity of the current process 1/8.
② rewrite sizeOf Method , Calculate the size of each picture to be cached .
Be careful : The total capacity of the cache should be consistent with the size of each cache object .
3.LruCache Realization principle
LruCache The core idea of , To maintain a list of cached objects , The arrangement of the object list is implemented according to the access order , That is, objects that have not been accessed , Will be at the end of the team , About to be eliminated , Recently accessed objects will be placed at the head of the team , To be eliminated .
As shown in the figure below :
This queue is made up of LinkedHashMap Maintenance of .LinkedHashMap By an array of + Two way linked list data structure implementation . The structure of two-way linked list can realize the access order and insertion order , bring LinkedHashMap Medium <key,value> Yes, in a certain order .
Specify... Through the following constructor LinkedHashMap Is the structure of bidirectional linked list in access order or insertion order .
public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) {
super(initialCapacity, loadFactor);
this.accessOrder = accessOrder;
}
among accessOrder Set to true The order of access , by false, Is the insertion order .
Explain with specific examples :
① When set to true when
public static final void main(String[] args) {
LinkedHashMap<Integer, Integer> map = new LinkedHashMap<>(0, 0.75f, true);
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);
map.get(1);
map.get(2);
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
Output results :
0:0
3:3
4:4
5:5
6:6
1:1
2:2
That is, the last output of the most recent access , This is just enough LRU The idea of caching algorithm . so LruCache Clever implementation , Is to make use of LinkedHashMap This data structure .
The following is LruCache Look at the source code , How to apply LinkedHashMap To add cache , Get and delete .
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);
}
from LruCache As you can see in the constructor of LinkedHashMap Access order .
(1)put() Method
public final V put(K key, V value) {
if (key == null || value == null) {
throw new NullPointerException("key == null || value == null");
}
V previous;
synchronized (this) {
putCount++; // The value of the inserted cache object plus 1
// Increase the size of the existing cache
size += safeSizeOf(key, value);
// towards map Add cache object to
previous = map.put(key, value);
// If there are already cached objects , Then the cache size is restored to the previous
if (previous != null) {
size -= safeSizeOf(key, previous);
}
}
//entryRemoved() It's an empty method , It can be realized by itself
if (previous != null) {
entryRemoved(false, key, previous, value);
}
// Resize cache ( Key methods )
trimToSize(maxSize);
return previous;
}
put() The method is not difficult , The important thing is to add cache objects , call trimToSize() Method to determine whether the cache is full , If full, delete the least recently used algorithm .
trimToSize() Method :
public void trimToSize(int maxSize) {
while (true) { // Dead cycle
K key;
V value;
synchronized (this) {
// If map Empty and cache size It's not equal to 0 Or cache size Less than 0, Throw an exception
if (size < 0 || (map.isEmpty() && size != 0)){
throw new IllegalStateException( getClass().getName() + ".sizeOf() is reporting inconsistent results!");
}
// If the cache size size Less than maximum cache , perhaps map It's empty , There is no need to delete the cache object , Out of the loop
if (size <= maxSize || map.isEmpty()) {
break;
}
// The iterator gets the first object , That is, the element at the end of the team , The least recently accessed element
Map.Entry<K, V> toEvict = map.entrySet().iterator().next();
key = toEvict.getKey();
value = toEvict.getValue();
// Delete the object , And update the cache size
map.remove(key);
size -= safeSizeOf(key, value);
evictionCount++;
}
entryRemoved(true, key, value, null);
}
}
trimToSize() Method to delete LinkedHashMap The element at the end of the squadron , That is, the least recently visited , Until the cache size is less than the maximum .
When calling LruCache Of get() Method to get the cached objects in the collection , On behalf of a visit to the element , The queue will be updated , Keep the entire queue in order of access . This update process is in LinkedHashMap Medium get() Method .
(2)get() Method
public final V get(K key) {
if (key == null) {
throw new NullPointerException("key == null");
}
V mapValue;
synchronized (this) {
// Get the corresponding cache object .get() Method will implement the function of updating the accessed element to the queue header
mapValue = map.get(key);
if (mapValue != null) {
hitCount++;
return mapValue;
}
missCount++;
}
}
among LinkedHashMap Of get() The method is as follows :
public V get(Object key) {
LinkedHashMapEntry<K,V> e = (LinkedHashMapEntry<K,V>)getEntry(key);
if (e == null)
return null;
// The key method to realize sorting
e.recordAccess(this);
return e.value;
}
call recordAccess() The method is as follows :
void recordAccess(HashMap<K,V> m) {
LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
// Determine whether it is access sorting
if (lm.accessOrder) {
lm.modCount++;
remove(); // Delete this element
// Move this element to the head of the queue
addBefore(lm.header);
}
}
so LruCache A collection is maintained in LinkedHashMap , The LinkedHashMap It is sorted in access order . When calling put() When the method is used , Will add elements to the combination , And call trimToSize() Determine whether the cache is full , If it's full, use LinkedHashMap Deletes the tail of the queue element using the iterator , That is, the least recently accessed element . When calling get() Method to access the cache object , Will call LinkedHashMap Of get() Method to obtain the corresponding set element , At the same time, the element will be updated to the team head .
边栏推荐
- 头部物联网SaaS公司G7、E6合并,能否成为to B领域的“美团”?
- How to find and delete duplicate documents in endnote
- VersionFilter 版本控制
- Unity-获取XML文件的内容信息
- 科研实习 | 北京大学可视化与可视分析实验室招收暑期实习生和推免研究生
- CREMB Pro 后台子管理员 403 问题分析
- Elk is not fragrant! I use grayog, which is much lighter
- 腾讯云数据库TDSQL|像这样的高考,其实我们每天都在经历
- Experience sharing in application for assessment of doctor of management - Information Collection
- 外出旅行如何确保人身及财产安全
猜你喜欢

vscode 配置 文件保存时自动格式化

科研实习 | 北京大学可视化与可视分析实验室招收暑期实习生和推免研究生

Sphereex officially open source the database mesh oriented solution pisanix

【GAMES101】作业1--MVP(模型、视图、投影)变换

一款高颜值开源知识管理工具

Zhongyuan bank unified log platform

With so many universities, the number of people taking the postgraduate entrance examination has risen sharply! Up to 70%!

Unity-获取XML文件的内容信息
老师送给学生的毕业赠言如何用云便签记录整理

DZ plug-in - free DZ plug-in collection of all plug-in functions
随机推荐
Right click the project to add a reference, prompting that the call to the COM component returned an error HResult e_ FAIL
Leetcode 1957. Delete characters to make the string better (yes, one pass)
Oracle分页
Unity-获取XML文件的内容信息
Leetcode 1967. 作为子字符串出现在单词中的字符串数目
一款高颜值开源知识管理工具
VersionFilter 版本控制
Gesture interaction across the space, performing "handy" in the real world
力扣解法汇总497-非重叠矩形中的随机点
Differences between gtf/gff documents and their mutual conversion (Reprint)
科研实习 | 北京大学可视化与可视分析实验室招收暑期实习生和推免研究生
安装idea
Cloud security daily 220609: Cisco cloud application policy infrastructure controller found privilege upgrade vulnerability, which needs to be upgraded as soon as possible
Real topic of the 13th provincial competition of the Blue Bridge Cup in 2022 - block painting
pyepics数组 -- 4
Memory concept
Running the code, I want to add a progress bar to see the running progress of the following code in real time. How can I break it?
八连冠!浪潮云连续8年蝉联中国政务云市场第一位
[blockbuster] the cloud store brand has been upgraded, and the surprise award is coming! Participate in interactive sampling of Huawei's latest folding mobile phones
运行代码,想加个进度条实时看以下代码运行进度,怎么破?