レガシー プロジェクトでの LRU キャッシュの実装を以下に示します。このプロジェクトではSoftReference
、キー オブジェクトではなく値オブジェクトの使用について質問があります。
ここに実装があります
public class LRUCacheImpl<K, V> implements LRUCache<K, V> {
// SoftReference is used for a memory friendly cache.
// The value will be removed under memory shortage situations and
// the keys of the values will be removed from the cache map.
private final Map<K, SoftReference<V>> cache;
public LRUCacheImpl(final int cacheSize) {
// 'true' uses the access order instead of the insertion order.
this.cache = new LinkedHashMap<K, SoftReference<V>> (cacheSize, 0.75f, true) {
private static final long serialVersionUID = 1L;
@Override
protected boolean removeEldestEntry(Map.Entry<K, SoftReference<V>> eldest) {
// When to remove the eldest entry i.e. Least Recently Used (i.e. LRU) entry
return size() > cacheSize; // Size exceeded the max allowed.
}
};
}
@Override
public V put(K key, V value) {
SoftReference<V> previousValueReference = cache.put(key, new SoftReference<V>(value));
return previousValueReference != null ? previousValueReference.get() : null;
}
@Override
public V get(K key) {
SoftReference<V> valueReference = cache.get(key);
return valueReference != null ? valueReference.get() : null;
}
}
アプリケーションが OutOfMemory(OOM) に到達しようとしている場合、GC はソフト到達可能なオブジェクトのメモリを再利用します。同じロジックを適用すると、値のメモリのみを再利用する必要があります (ソフト参照は値オブジェクトに対してのみ作成されるため)。
しかし、ここにファイルの先頭にあるコメントがあります
// SoftReference is used for a memory friendly cache. // The value will be removed under memory shortage situations and // the keys of the values will be removed from the cache map.
私の質問は、アプリが OOM に到達すると、対応するキー オブジェクトがマップからどのように削除されるかです。キーもソフト参照でラップするべきではありませんか?
cache.put(new SoftReference<K>(key), new SoftReference<V>(value));