본문 바로가기
Programming/JAVA

맵 사용에 따른 메모리 누수

by 유주원 2013. 1. 8.

가비지 컬렉터에서는 논리적으로 더이상 사용하지 않는 객체에 대한 정리 작업을 실행한다. 하지만 만약 이러한 객체가 맵 안에 존재하고 있다면 어떻게 될까?

정리 작업을 실행해야 할까 말아야 할까??

정답은 '정리 작업을 실행하지 않음' 이다.

아래의 예제 소스를 보면,

public class Manager {

private Map<Key , Value> map = new Hashmap<Key, Value>();

public void setData(Key k, Value v){

map.put(k, v);

}

public Object getData(Key k){

  return map.get(k);

}

public void removeData(Key k){

map.remove(k);

}


해시 맵을 사용할 때 위와 같은 방법으로 사용을 많이 한다.

위의 코드에서 발생할 수 있는 잠재적 문제는 무엇일까?

위의 코드에서는 개발자가 직접 데이터의 생명 주기를 알고 있고 정확히 제거를 해주어야지 가비지 컬렉팅이 된다는 사실이다.

만에 하나 개발자가 데이터의 생명 주기를 정확히 알지 못하고 개발을 진행할 경우 메모리 누수의 원인으로 작동할 것이다.

메모리 누수를 막기 위한 Map 사용의 방법 중 하나로 WeakHashMap의 사용이 있다.

개발자가 수동으로 가비지 컬렉팅을 하는 게 아니라 내부적으로 더 이상 참조가 없을 시, 가비지 컬렉팅을 해주는 Map 클래스이다.

public class Manager {

private Map<Key, Value> map = new WeakHashmap<Key, Value>();

public void setData(Key k, Value v){

map.put(k, v);

}

public void getData(Key k){

return map.get(k);

}

}


WeakHashmap 내부에는 expungeStaleEntries()라고 하는 reference queue를 폴링하고 관련 매핑을 제거하는 private 함수가 동작하고 있다.

무엇이든지, 자동은 그만큼의 side effect를 가질 것으로 예상된다. (아마 성능상 느려지지 않을까하는...) 

가급적이면 꼼꼼한 코딩 습관으로 Hashmap을 쓰도록 하자!