[컴][자바][안드로이드] WeakHashMap 에서 주의할 점

weakhashmap 에서 size 가 바뀌는 경우 / weakhashmap 에서 스스로 data 가 사라지는 경우


Map 을 자주 사용하는 편인데, WeakHashMap 이 그냥 많이들 쓰는 듯 해서 아무데나 마구잡이로 쓰고 있었는데, 문제가 발생했다. ^^;;;

갑자기 Map 의 key 가 사라졌다. API 문서(ref. 1) 를 보면 그런 경우에 대한 경고를 하고 있었다. 여하튼 그래서 조금 더 정리를 했다.


WeakHashMap

이녀석의 key 는 더이상 쓸모가 없다고 JVM 등이 판단을 하면, 자기 마음대로 garbage collector(GC) 에게 넘겨버리고 null 을 return 한다. 물론 이때 알아서 key 와 value 의 값의 메모리를 정리한다.[ref. 1]

판단의 기준은 reference 가 얼마나 되고 있느냐로 판단한다.[ref. 2] 근데 weak reference 만 가지고 있다면 이 녀석은 GC 가 마음대로 없애버릴 수 있다.

그래서 쉽게 얘기하면, 이녀석으로 만들어 놓은 Map 의 size 가 바뀔 가능성이 다분하다.

그렇기 때문에 절대 사라져서는 안될 녀석에 대한 Map 을 만들 생각이라면 이녀석을 사용하면 안된다.

그런데 이녀석을 왜 만들어 놨을까?
그것에 대한 대답은 ref. 2 에서 해 준다. garbage collecting 을 잘 해서 메모리 누수(Memory leak) 이 안되게 해주는 장점을 가진다.

지금 이녀석을 사용하고 있는데, 대부분의 경우에서는 크게 문제를 보이지 않는다.

특히 Cache 를 위한 map 을 만들때는 충분하다. 왜냐하면 어차피 cache 는 일정 용량(capacity) 이상에서는 없애야 하는 녀석들이니, null 을 return 하면 다시 data 를 가져오면 된다.

그런데 static 한 녀석으로 사용하려고 한다면, weak reference 를 사용하는 WeakHashMap 은 어울리지 않는다. 왜냐하면, weak reference 만 가지고 있는 상태에서는 언제 GC 가 없애버릴 수 알 수 없기 때문이다.

그러므로 이럴 때는 그냥 일반적인 HashMap 등을 사용하는 것이 훨씬 나은 선택일 수 있다.


예제

아래에서 WeakHashMap 을 사용했다. 그런데 한번의 access 후에 key 가 사라져 버렸다. 아마 reference 가 처음 put() 할 때 +1 되고는 get() 하면서 -1 이 되는 듯 하다.
여하튼 그래서 아래 경우에는 쓸 수 없었다.

public class ItemAdapter extends BaseAdapter{
 private WeakHashMap<String, String> mStateMap;
 
 
 ...
 public synchronized void init(Activity c){
  ...
  mFilesStateMap.put(filename, STATE_PLAY);
 }
 
 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
  ...
  holder.calendarBottom.setText(mFilesStateMap.get(item.getFileName()));
  ...
 }
}

하지만 local 에서 new 를 해서 local 에서만 사용하는 경우에는 괜찮은 듯 하다. 어차피 local 에서는 많이 쓸 일도 없고, 중간에 GC 를 부를 일도 많지 않은 듯 하기 때문이다. (물론 위험의 가능성은 언제나 열려 있다. ^^;;)


See Also

  1. THREAD POOL 과 HASHMAP 자료들


References

  1. javase 6 API 문서 WeakHashMa
  2. [JAVA] WeakHashMap의 사용
  3. Java theory and practice: 메모리 누수와 약한 참조 (한글)

댓글 없음:

댓글 쓰기