LRU (Least recently used) is a very common resource scheduling strategy, which conforms to the 20/80 principle and tends to retain the most recently accessed resource objects when the resource reaches the upper limit.
Based on the LRU implementation of the cache object in Android, namely LruCache, there are two implementations: Android.support.v4.util.LruCache and Android.util.LruCache, respectively, wherein the former is designed in accordance with LRU,
The latter, when resources are insufficient, the most recent frequently accessed resource objects, when used, need to pay attention to this, here to analyze the source code of Android.support.v4.util.LruCache.
LRUCache is a generic class whose class diagram is as follows:
It can be seen that LRUCache is based on Linkedhashmap, Linkedhashmap is not thread-safe, so lrucache through the monitor mode, the API (inside) on the Lrucahce object
Add synchronized lock to implement LRUCache thread safety. The LRUCache constructor is as follows: where 0.75 indicates that table usage is >=75% within LINKEDHASHMAP, the table size needs to be increased so that the hash table is more evenly distributed and avoids degradation to the pure list.
Where Accessorder is very important, if true, the Head->tail order of the linked list is "recently least accessed, recently accessed", that is, when an object is accessed, it is inserted into the tail,
As a new tail, if Accessorder is false, the Access object's location is not moved when accessed. Accessorder=true The design requirements of the symbol LRUCache.
Size in LRUCache is flexible and lrucache can be defined according to business requirements, such as creating a Bitmap cache, such as lrucache<string, Bitmap>
This size can represent the total size of the bitmap in the cache (in kilobytes), LRUCache provides a function to calculate size, and the caller can be overridden in the LRUCache subclass to define, but need to maintain its meaning (unit) and
MaxSize consistent, such as:
Below is a brief analysis of Lrucache.get and put, where get and put are locked when using map internally, get core code is as follows:
As you can see, LRUCache is not allowed to be null, and when there is a value corresponding to key, return directly, here Linkedhashmap.get operation
The value will be moved to tail, as follows:
You can see that Linkedhashmap is a two-way loop linked list, and then look at the put operation:
The core implementation of TrimToSize is as follows:
You can see that the head-pointing item, which is the least recently used item, is cleaned up, while the Android.util.LruCache trimtosize cleans up the tail:
Summarized as follows:1. LRU is a resource scheduling policy that tends to clean up least recently accessed resource objects
There are two LRUCache in 2.Android, using the support-v4 bag
3.LruCache Linkedhashmap-based thread-safe class, implemented by locks, the most recently accessed resource objects are put into tail by linkedhashmap.get
, resource recycling is implemented in put.
4.LruCache subclasses typically need to rewrite sizeof to define the size in the cache
LRUCache Source Code Analysis