Android LRUCache Implementation and use (Android memory optimizer)

Source: Internet
Author: User

What is LRUCache?

What is the LRUCache implementation principle?

These two questions can actually answer as a question, know what is LruCache, only then know the LruCache realization principle; The full name of the LRU is least recently used, the least recently used! So we can infer the principle of LruCache: To remove the least recently used data from the cache, to retain the most frequently used data, how to implement the specific code, we go into the source to see.

LRUCache Source Code Analysis
PublicClass Lrucache<k, v> {Cache Map Collection, why use LinkedhashmapBecause that's right. After you have cached values, sort them to ensure thatThe least used value is removed the next timePrivate final linkedhashmap<k, v> map;The current cached valuePrivateint size;Maximum ValuePrivateint maxSize;Number of additions to the cachePrivateint putcount;Number of CreationPrivateint createcount;Number of removedPrivateint evictioncount;Number of HitsPrivateint hitCount;Missing numberPrivateint misscount;Instantiate Lru, need to pass in the maximum value of the cacheThe maximum value can be a number, such as the number of objects, or the size of the memoryFor example, the maximum memory can only cache 5 megabytesPublicLruCache (int maxSize) {if (MaxSize <=0) {ThrowNew IllegalArgumentException ("MaxSize <= 0"); }This.maxsize = maxSize;This.map =New Linkedhashmap<k, V> (0,0.75f,true); }Reset the value of the maximum cachePublicvoidResizeint maxSize) {if (MaxSize <=0) {ThrowNew IllegalArgumentException ("MaxSize <= 0"); } synchronized (This) {This.maxsize = maxSize; } trimtosize (MaxSize); }Get cache value from keyPublic final VGet (K key) {if (key = =NULL) {ThrowNew NullPointerException ("Key = = null"); } V Mapvalue; Synchronized (This) {Mapvalue = map.Get (key);if (mapvalue! =NULL) {hitcount++;return mapvalue; } misscount++; }If not, users can go to create V Createdvalue = Create (key);if (Createdvalue = =NULL) {ReturnNull } synchronized (This) {createcount++; mapvalue = Map.put (key, Createdvalue);if (mapvalue! =NULL) {There is a conflict so undo the last put Map.put (key, Mapvalue); }else {The size of the cache is changed by sizes + = safesizeof (key, Createdvalue); } }There's no removal, just a change of position.if (mapvalue! =NULL) {entryremoved (False, Key, Createdvalue, Mapvalue);return mapvalue; }else {Determine if the cache is out of bounds trimtosize (maxSize);return createdvalue; } }Add the cache, just like the code after the create of this method abovePublic final VPut (K key, VValue) {if (key = =null | |Value = =NULL) {ThrowNew NullPointerException ("key = = NULL | | Value = = null "); } V Previous; Synchronized (This) {putcount++; size + safesizeof (key,Value); Previous = Map.put (key,Value);if (Previous! =NULL) {Size-= safesizeof (key, previous);}}if (Previous! =NULL) {entryremoved (False, key, previous,Value); } trimtosize (MaxSize);return previous; }Detect if the cache is out of boundsPrivatevoidTrimToSize (int maxSize) {while (true) {K key; VValue Synchronized (This) {if (Size <0 | | (Map.isempty () && Size! =0)) {ThrowNew IllegalStateException (GetClass (). GetName () +". SizeOf () is reporting inconsistent results!"); }If not, then returnif (size <= maxSize) {Break }The following code indicates that the maximum range map.entry<k has been exceeded, v> toevict =NullFor (Map.entry<k, v> entry:map.entrySet ()) {toevict = Entry;}if (toevict = =NULL) {Break }Remove the last one, which is the least used cache key = Toevict.getkey ();Value = Toevict.getvalue (); Map.Remove (key); Size-= safesizeof (Key,Value); evictioncount++; } entryremoved (True, Key,ValueNULL); } }Manual removal, user callsPublic final VRemove (K key) {if (key = =NULL) {ThrowNew NullPointerException ("Key = = null"); } V Previous; Synchronized (This) {previous = Map.Remove (key);if (Previous! =NULL) {Size-= safesizeof (key, previous);}}if (Previous! =NULL) {entryremoved (False, key, previous,NULL); }return previous; }Here the user can rewrite it for data and memory recycling operationsProtectedvoidEntryremoved (Boolean evicted, K key, v OldValue, v newvalue) {}Protected VCreate (K key) {ReturnNull }PrivateIntSafesizeof (K key, VValue) {int result = SizeOf (key,Value);if (Result <0) {ThrowNew IllegalStateException ("Negative size:" + key +"=" +Value); }return result; }This method to pay special attention, and we instantiate LruCache maxSize to echo, how to do echo, such as maxSize size for the number of cache, here is the return 1 OK, if the size of the memory, if 5M, this can not be the number, This is supposed to be the size of each cache value, and if it is Bitmap, this should be bitmap.getbytecount ();ProtectedIntSizeOf (K key, VValue) {Return1; }Empty cachePublic finalvoidEvictall () {TrimToSize (-1);-1 'll evict 0-sized elements}Public synchronized finalIntSize () {return size; }Public synchronized finalIntMaxSize () {return maxSize; }Public synchronized finalIntHitCount () {return hitCount; }Public synchronized finalint misscount () {return MissCount;} public synchronized final int  Createcount () {return Createcount;} public synchronized final int  Putcount () {return Putcount;} public synchronized final int  Evictioncount () {return Evictioncount;} public synchronized final map<k, v> snapshot () {return new linkedhashmap<k, v> (map);}}     
LruCache use

Let's take a look at two diagrams of memory usage

                             图-1

                            图-2

The above analysis of the memory analysis is the same application data, the only difference is that figure 1 does not use LruCache, and figure 2 used LruCache; it can be very obvious to see that figure 1 of the memory use is significantly larger, basically is around 30M, The memory usage of Figure 2 is basically around 20M. This saves nearly 10M of memory!

OK, the implementation code is posted below

/** * Created by Gyzhong on 15/4/5. */PublicClassLrupageadapterExtendsPageradapter {Private list<string> Mdata;Private lrucache<string,bitmap> Mlrucache;Privateint mtotalsize = (int) runtime.getruntime (). TotalMemory ();Private Viewpager Mviewpager;PublicLrupageadapter (Viewpager viewpager,list<string> data) {mdata = data; Mviewpager = Viewpager;/* Instantiate lrucache*/Mlrucache =New Lrucache<string,bitmap> (mtotalsize/5) {/* This method is called when the cache is larger than the maximum value we set, and we can use it to do the memory release operation.@OverrideProtectedvoidEntryremoved (Boolean evicted, String key, Bitmap OldValue, Bitmap newvalue) {Super.entryremoved (evicted, Key, OldValue, NewValue);if (evicted && oldValue! =NULL) {oldvalue.recycle ();}}/* Create bitmap*/@OverrideProtected BitmapCreate (String key) {Finalint resId = Mviewpager.getresources (). Getidentifier (Key,"Drawable", Mviewpager.getcontext (). Getpackagename ());Return Bitmapfactory.decoderesource (Mviewpager.getresources (), resId); }/* Get the size of each value */@OverrideProtectedIntSizeOf (String key, Bitmap value) {return Value.getbytecount (); } } ; }@OverridePublic ObjectInstantiateitem (ViewGroup container,int position) {View view = Layoutinflater.from (Container.getcontext ()). Inflate (R.layout.view_pager_item,NULL); ImageView ImageView = (ImageView) View.findviewbyid (R.id.id_view_pager_item); Bitmap Bitmap = Mlrucache.get (mdata.get (position)); Imageview.setimagebitmap (bitmap); Container.addview (view);return view;} @Override public void destroyitem (ViewGroup container, int position, object object) { Container.removeview ((View) object); } @Override public int GetCount () { return mdata.size ();} @Override Public boolean isviewfromobject (View view, Object object) { return view = = Object;}} 
Summarize

1, LruCache is a caching mechanism based on LRU algorithm;
2, the LRU algorithm principle is to remove the least recently used data, of course, the premise is that the current amount of data is greater than the maximum value set.
3, LruCache does not really release memory, just remove the data from the map, the actual release of memory or the user to manually release.

 

Android LRUCache Implementation and use (Android memory optimizer)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.