LRU는 Least Recently Used의 약자로, 간단하게 최근에 사용된 넘을 캐시에 유지한다는 것이 LRUCache 입니다..
간단하게 아래와 같이 만들 수 있습니다.

1. 코드 속에서 간단하게 만들기..
final int MAX_ENTRIES = 100;
Map cache = new LinkedHashMap(MAX_ENTRIES+1, .75F, true) {
    // This method is called just after a new entry has been added
    public boolean removeEldestEntry(Map.Entry eldest) {
        return size() > MAX_ENTRIES;
    }
};

2. LinkedHashMap을 이용해서 만들기..

public class LRUCache<K,V> extends LinkedHashMap<K,V> {
    private int lruSize;

    public LRUCache(int size) {
        lruSize = size;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry eldest) {
        return size() > lruSize;
    }
}

보통 위에처럼 하게 되면 그냥 됩니다..
그러다가 점점 메모리 릭이 납니다.. ^^;;

그래서 해결책을 찾아보니, https://code.google.com/p/reflection-dsl/source/browse/trunk/ReflectionDsl/src/br/com/bit/ideias/reflection/cache/LRUCache.java?spec=svn204&r=204 에서는 Value에 해당하는 객체를 SoftReference로 래핑해서 땜빵(?)하고 있네요.. ^^;;

그래서 저같은 경우에는 명시적으로 객체를 삭제하는 코드를 입력해서 사용하고 있습니다.
아래의 코드를 통해서 잠재적으로 발생할 수 있는 메모리릭을 없애 주세요.. ^^
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        boolean isRemove = size() > maxsize;
       
        if (isRemove) {
            Object obj = this.get(eldest.getKey()); 
            if(obj instanceof BufferedWriter) { // V가 BufferedWriter 인스턴스임..
                try {
                    ((BufferedWriter)obj).close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            this.remove(eldest.getKey());
        }

        return isRemove;
    }







저작자 표시

java 1.4 Collections API에 새롭게 첨가된 java.util.LinkedHashMap 클래스는 HashMap처럼 해쉬테이블에 기반을 둔 Map 클래스 입니다. LinkedHashMap이 다른 점은 맵 엔트리에서 실행되는 링크된 리스트를 관리할 수 있고 또한 그 엔트리에 대해서 예측할 수 있는 반복 작업을 수행할 수 있다는 것이다. 대부분 이 순서는 맵에 엔트리가 추가된 순서대로 되고 가끔씩 아주 유용한 특징으로 사용할 수 있는 상황도 있습니다. 

LinkedHashMap은 생성자의 세 번째 인자로 true 값을 넘겨줌으로써 가장 최근에 접근(즉 조회되거나 설정된) 순서에서 가장 오래 전에 접근된 순서로 엔트리 순서를 설정할 수 있다.

그리고, LinkedHashMap의 removeEldestEntry()를 새로운 Entry가 추가될 때 마다 호출을 하게되면, 이 메소드가 true를 반환하면 맵에서 '가장 오래된' Entry, 즉 가장 오래 전에 입력되거나 사용된 것은 자동적으로 삭제된다. removeEldestEntry()의 기본값으로 항상 false를 반환하지만 맵이 정해진 어떤 최고 크기에 다다르면 true 값을 반환하도록 오버라이드 할 수 있다. 이와 같이 하면 LRU(least-recently-used) 캐시를 만들 수 있는 것입니다.

public class LRUCache extends java.util.LinkedHashMap {
    public LRUCache(int maxsize) {
        super(maxsize*4/3 + 1, 0.75f, true);
        this.maxsize = maxsize;
    }
    protected int maxsize;
    protected boolean removeEldestEntry() {
        return size() > maxsize;
    }
}