Picture memory cache control

From the Internet to find yourself finishing the next:


public class MemoryCache
    {
        private static final String TAG = "MemoryCache";
        /**
         * 放入缓存时是个同步操作
         * LinkedHashMap构造方法的最后一个参数true代表这个map里的元素将按照最近使用次数由少到多排列,即LRU
         * 这样的好处是如果要将缓存中的元素替换,则先遍历出最近最少使用的元素来替换以提高效率
         */
        private Map<String, Bitmap> mCache = Collections.synchronizedMap(new LinkedHashMap<String, Bitmap>(10, 1.5f, true));
        /**
         * 缓存中图片所占用的字节,初始0,将通过此变量严格控制缓存所占用的堆内存
         */
        private long mSize = 0;
        /**
         * 缓存只能占用的最大堆内存
         */
        private long mLimit = 1000000;

        public MemoryCache() {
            setLimit(Runtime.getRuntime().maxMemory() / 10);
        }

        /**
         * 设置内存使用上限
         * @param limit
         */
        public void setLimit(long limit)  {
            mLimit = limit;
            Log.i(TAG, "MemoryCache will use up to " + (mLimit / 1024. / 1024.) + "MB");
        }

        /**
         * 获取内存中缓存的图片资源
         *
         * @param key
         * @return
         */
        public Bitmap get(String key) {
            try {
                if (! mCache.containsKey(key)) return null;
                return mCache.get(key);
            } catch (NullPointerException ex) {
                return null;
            }
        }

        /**
         * 将图片资源缓存到内存
        *
         * @param key
         * @param bitmap
         */
        public void put(String key, Bitmap bitmap) {
            try {
            if (mCache.containsKey(key))
                mSize -= getSizeInBytes(mCache.get(key));
                mCache.put(key, bitmap);
                // 累计当前缓存已使用的内存大小
                mSize += getSizeInBytes(bitmap);
                checkSize();
            } catch (Throwable th) {
                th.printStackTrace();
            }
        }

        /**
         * 检测图片缓存的内存占用
         */
        private void checkSize()
        {
            Log.i(TAG, "cache size=" + mSize + " length=" + mCache.size());
            if (mSize > mLimit) {
                // 先遍历最近最少使用的元素
                Iterator<Map.Entry<String, Bitmap>> iterator = mCache.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, Bitmap> entry = iterator.next();
                    mSize -= getSizeInBytes(entry.getValue());
                    iterator.remove();
                    if (mSize <= mLimit)
                        break;
                }
                Log.i(TAG, "Clean cache. New size " + mCache.size());
            }
        }

        /**
         * 清空内存缓存
         */
        public void clear() {
            mCache.clear();
        }

        /**
         * 图片占用的内存
         *
         * @param bitmap
         * @return
         */
        long getSizeInBytes(Bitmap bitmap) {
            if (bitmap == null)
                return 0;
            return bitmap.getRowBytes() * bitmap.getHeight();
        }
    }

First image buffer memory limits the size of the heap memory, each time a picture is determined whether the time exceeds the size limit Riga into cache, if it exceeds the minimum image removed from use and removal, of course, if there is not this way, for to do soft references are possible, both aim is to maximize the use of all existing in-memory image cache, to avoid duplication of spamming increase the burden on GC, OOM often overflow because the significant increase in transient memory and garbage collection is not timely due. LinkedHashMap only difference between the two is that the pictures in the cache before removing out no GC will not be recovered, and SoftReference in the image cache will be recovered at any time when no other references to GC saved. Therefore, the effective use of LinkedHashMap hit this cache LRU algorithm is more conducive to the picture, of course, then the effect of both with the use of better, that is, removed from the cache into SoftReference LinkedHashMap in years, this is the secondary cache memory, there interested extraordinary shoes a try.

Original: http://www.eoeandroid.com/thread-254866-1-1.html

Reproduced in: https: //my.oschina.net/zhouz/blog/213181

Guess you like

Origin blog.csdn.net/weixin_34343689/article/details/91728519