LruCacheの使用とソースの詳細解析
8886 ワード
最初に引用を説明する準備ができましたが、ネット上には多くの優れた枠組みがあります.キャッシュについてはこれは基本的に全部使っています.
LRUは、Least Recently Usedが最近少なくともアルゴリズムを使用する.実はLruCacheの役割はキャッシュの要素を並べ替えることです.設定されたメモリ値を超えると最低使用されます.一番早い元素を使って先に回収します.
LruCacheの声明:
LRUは、Least Recently Usedが最近少なくともアルゴリズムを使用する.実はLruCacheの役割はキャッシュの要素を並べ替えることです.設定されたメモリ値を超えると最低使用されます.一番早い元素を使って先に回収します.
LruCacheの声明:
LruCache , 。
。 , ( , , , , ,LruCache ):
//lrucache , remove
int cacheSize = 4; //
LruCache bitmapCache = new LruCache(cacheSize) {
//
protected int sizeOf(String key, Bitmap value) {
return 1;
}
}}
, 。
LruCache :
//lrucache , remove
int cacheSize = 4 * 1024 * 1024; // 4MiB
LruCache bitmapCache = new LruCache(cacheSize) {
// bitmap
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount();
}
}}
//
public void setItem(String key,Bitmap bitmap){
cache.put(key, bitmap);
}
//
public Bitmap getItem(String key){
return cache.get(key);
}
LruCache , , 1/8. 。 :
, :
// map, lru ,
private final LinkedHashMap map;
//
private int size;
//
private int maxSize;
//remove
private int evictionCount;
//
private int hitCount;
//
private int missCount;
//
public LruCache(int maxSize) {
if (maxSize <= 0) {
throw new IllegalArgumentException("maxSize <= 0");
}
this.maxSize = maxSize;
// map
this.map = new LinkedHashMap(0, 0.75f, true);
}
public void resize(int maxSize) {
if (maxSize <= 0) {
throw new IllegalArgumentException("maxSize <= 0");
}
synchronized (this) {
this.maxSize = maxSize;
}
trimToSize(maxSize);
}
// map
public final V get(K key) {
if (key == null) {
throw new NullPointerException("key == null");
}
V mapValue;
synchronized (this) {
mapValue = map.get(key);
if (mapValue != null) {
hitCount++;
return mapValue;
}
missCount++;
}
V createdValue = create(key);
if (createdValue == null) {
return null;
}
synchronized (this) {
createCount++;
mapValue = map.put(key, createdValue);
if (mapValue != null) {
// There was a conflict so undo that last put
map.put(key, mapValue);
} else {
size += safeSizeOf(key, createdValue);
}
}
if (mapValue != null) {
entryRemoved(false, key, createdValue, mapValue);
return mapValue;
} else {
trimToSize(maxSize);
return createdValue;
}
}
//
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++;
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;
}
// size>maxsizes,
public void trimToSize(int maxSize) {
while (true) {
K key;
V value;
synchronized (this) {
if (size < 0 || (map.isEmpty() && size != 0)) {
throw new IllegalStateException(getClass().getName()
+ ".sizeOf() is reporting inconsistent results!");
}
if (size <= maxSize) {
break;
}
Map.Entry toEvict = map.eldest();
if (toEvict == null) {
break;
}
key = toEvict.getKey();
value = toEvict.getValue();
map.remove(key);
size -= safeSizeOf(key, value);
evictionCount++;
}
entryRemoved(true, key, value, null);
}
}
//
public final V remove(K key) {
if (key == null) {
throw new 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;
}
// ( )
protected int sizeOf(K key, V value) {
return 1;
}
//
public final void evictAll() {
trimToSize(-1); // -1 will evict 0-sized elements
}
, , map 。 lruCache
LinkedHashMap 。
LinkedHashMap,HashMap,AbstractMap,Map , <<LinkedHashMap >>, :