LruCacheの原理を浅く分析する
1575 ワード
Androidは、2.3以降AndroidがGCを頻繁に呼び出すため、ソフトリファレンスキャッシュのデータが解放されやすいという.
LruCacheはLinkedHashMapを使用してメモリのキャッシュを簡単に実現し、ソフトリファレンスはなく、強いリファレンスです.追加したデータが設定した最大値より大きい場合は、最初にキャッシュしたデータを削除してメモリを調整します.彼の主な原理はtrimToSize法にある.2つの主要な変数sizeとmaxSizeを理解する必要があります
maxSizeは構築方法によって初期化された値で、このキャッシュがキャッシュできる最大値はいくらであるかを示しています.
sizeはキャッシュの追加と削除で値を更新し、safeSizeOfという方法で値を更新します.safeSizeOfはデフォルトで1を返しますが、一般的にはmaxSizeに基づいてこの方法を書き換えます.例えば、maxSizeがKBを表すとすると、KB単位でその項目が占めるメモリサイズを返します.
異常以外はまずsizeがmaxSizeを超えているかどうかを判断し、超えたら最初に挿入したキャッシュを取り出し、空でなければ削除し(一般的にmapが空でなければnullを返さない.彼は二重休暇チェーンテーブルだから)、sizeをその項目の大きさを減算する.この操作は、sizeがmaxSizeより小さいか、キャッシュが空になるまでループします.
LruCacheはLinkedHashMapを使用してメモリのキャッシュを簡単に実現し、ソフトリファレンスはなく、強いリファレンスです.追加したデータが設定した最大値より大きい場合は、最初にキャッシュしたデータを削除してメモリを調整します.彼の主な原理はtrimToSize法にある.2つの主要な変数sizeとmaxSizeを理解する必要があります
maxSizeは構築方法によって初期化された値で、このキャッシュがキャッシュできる最大値はいくらであるかを示しています.
sizeはキャッシュの追加と削除で値を更新し、safeSizeOfという方法で値を更新します.safeSizeOfはデフォルトで1を返しますが、一般的にはmaxSizeに基づいてこの方法を書き換えます.例えば、maxSizeがKBを表すとすると、KB単位でその項目が占めるメモリサイズを返します.
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);
}
}
異常以外はまずsizeがmaxSizeを超えているかどうかを判断し、超えたら最初に挿入したキャッシュを取り出し、空でなければ削除し(一般的にmapが空でなければnullを返さない.彼は二重休暇チェーンテーブルだから)、sizeをその項目の大きさを減算する.この操作は、sizeがmaxSizeより小さいか、キャッシュが空になるまでループします.