2014-10-29 2 views
1

값 개체에 대해서는 SoftReference 의 사용에 대해서는 질문이 있지만 키 개체에 대해서는 사용하지 않는 레거시 프로젝트에서 아래의 LRU 캐시 구현을 참조하십시오.지도에서 SoftReference 사용?

여기 애플리케이션 (OOM)에 도달하기에 OutOfMemory 관한 것이면

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; 
} 
} 

GC 부드럽게 도달 가능한 객체에 대한 메모리를 회수 구현이다. 동일한 논리를 적용하면 값에 대한 메모리 만 다시 계산해야합니다 (소프트 참조가 값 개체에만 생성됨).
그러나 여기가 내 질문은 키 오브젝트 앱 도달 OOM 한 번지도에서 제거하는 방법 대응이다

// 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. 

파일

의 시작 부분에있는 주석입니다. 열쇠도 소프트 레퍼런스가있는 으로 싸여서는 안됩니까?

cache.put(new SoftReference<K>(key), new SoftReference<V>(value)); 
+0

'Key' 그래서 키 소프트 심판 정말 많은 –

+0

도움이되지 않습니다 당신은 전체 클래스를 게시하는 코드를 만드는 것은, 값에 비해 크기가 작아 질 것으로 예상? 'removeEldestEntry' 메쏘드는이 맵에있는 키의 수를'cacheSize'로 제한해야 함을 암시하지만, 어디서나 적용되는 것을 보지 못합니다. – Eran

+0

@Eran 이것은 완전한 코드입니다. removeEldestEntry는 내부적으로 호출되는 반면에 조작은 – user3198603

답변

2

나는지도의 크기를 제한하는 LinkedHashMap 지원 사실을 알지 못했습니다. removeEldestEntry을 구현하면지도가 cacheSize 개 이상의 키를 갖지 못하게됩니다.

LinkedHashMap 구현에서 볼 수 있듯이 removeEldestEntry이 true를 반환하는 경우 새 항목을 추가하면 가장 오래된 항목이 제거됩니다.

void addEntry(int hash, K key, V value, int bucketIndex) { 
    createEntry(hash, key, value, bucketIndex); 

    // Remove eldest entry if instructed, else grow capacity if appropriate 
    Entry<K,V> eldest = header.after; 
    if (removeEldestEntry(eldest)) { 
     removeEntryForKey(eldest.key); 
    } else { 
     if (size >= threshold) 
      resize(2 * table.length); 
    } 
} 

따라서 가장 최근에 사용되지 않은 키는지도에서 제거됩니다.

이 생성자를 사용 :

this.cache = new LinkedHashMap<K, SoftReference<V>> (cacheSize, 0.75f, true) 

는 항목의 액세스 순서에 따라 정렬됩니다 것을 의미한다. 따라서 키를 가져 오거나 넣을 때마다 해당 항목을 목록 연결된 목록의 뒤로 이동합니다. 목록의 시작 부분에 가장 최근에 사용되지 않은 항목이 들어 있습니다.

그러므로 //the keys of the values will be removed from the cache map은 아마도 메모리 부족 상태에서 값을 제거하지 않고도 사용량이 가장 적은 키가 결국지도에서 제거된다는 사실을 나타냅니다.

+0

입니다. 하지만 여기에 내 질문은 '키가 소프트 레퍼런스로 래핑되지 않아야합니까?'라는 것입니다. 메모리가 부족한 경우 값이 아니라 키와 값이 모두 제거되는 것입니다. – user3198603

0

Reference의 줄 바꿈 키는 복잡한 경우 옵션입니다.
목표는 OOM을 피하면서 캐시에서 값을 가져 오지 않아서 불필요한 것들이 발생하지 않도록하는 것입니다. Reference의에서
그냥 포장 키는 표준지도 구현에 충분하지 않다 - 어떤 키를 동일하게 나타나지 않을 것
equals() & hashCode()을 무시하지 않고 : 아무것도
또 다른 접근 방식으로 Soft/WeakReference의를 사용하는 것입니다 ..., 제거, 발견 대체됩니다 Map.Entry s : 수행 방법의 예는 java.util.WeakHashMap<K, V>을 참조하십시오 (우발적 인 언급으로). 장점은 연약한 약점이 사라진 것을 발견하면 남아있는 강한 참고 문헌을 제거 할 수 있다는 것입니다.
그런 다음이 trove4j, Apache Commons Collections, Goldman Sachs ...