각각에 개념부터.

  • WeakReference
    • 말그대로, '약한' 참조 이다. '약한' 참조는 해당 객체에 대한 소멸을 막지 않는다. 즉, 어떤 객체에 대한 참조가 WeakReference 밖에 남아있지 않다면 그 객체는 gc(Garbage Collection) 의 대상이 된다.
    • 펼치기 - J2SE 5.0 api 문서의 설명 원문

  • SoftReference
    • WeakReference 보다는 약간 강한 참조이다. Soft reference 만 남아있는 객체는 메모리의 요청에 의한 gc 의 대상이 된다. 메모리의 남은 공간이 넉넉하다면 gc되지 않을 것이며, 메모리의 남은 공간이 얼마 없거나 하다면 gc 의 대상이 될 것이다.
      확실한건 vm 이 OutOfMemoryError 를 발생시키기 전에는 Soft reference 만 남아있는 객체가 gc의 대상이 된다는 점 정도고, 그 이외에는 vm 의 구현에 따라 다를 수 있다.
    • 펼치기 - J2SE 5.0 api 문서의 설명 원문


샘플 코드를 보자.

public class referenceTest {
 //테스트용 클래스. 별거 없다.
 public static class Inner {
  public String str;
  public Inner(String value) {
   this.str = value;
  }
    
  public String getStr(){
   return this.str;
  }
  
  public String toString() {
   return this.str;
  }
 }
  
 public static void main(String[] args) {
  try{
   
   //일반 참조. 객체를 그냥 생성해서 리스트에 넣고 gc 한다.
   List<Inner> tmpList = new ArrayList<Inner>();
   tmpList.add(new Inner("simple reference is alive."));
   System.gc();
   
   // gc 후 객체가 살아있는지 확인한다.
   for (Inner refer : tmpList) {
    if (refer == null) {
     System.out.println("refer is null.");
    }else {
     System.out.println(refer.getStr());
    }
   }
   
   //WeakReference.
   List<WeakReference> list = new ArrayList<WeakReference>();
   WeakReference<Inner> wr = new WeakReference<Inner>( new Inner("weak reference test obj is alive."));
   list.add(wr);
   
   //gargage collention 발생.
   System.gc();
   
   //gc 후 객체가 살아있는지 확인한다.
   for (WeakReference<Inner> refer : list) {
    if (refer == null) {
     System.out.println("refer is null.");
    }else {
     Inner inner = refer.get();
     if (inner == null) {
      System.out.println("referenced obj is null.");
     }else
      System.out.println(inner.getStr());
    }
   }
   
   //SoftReference.
   List<SoftReference> slist = new ArrayList<SoftReference>();
   SoftReference<Inner> sr = new SoftReference<Inner>( new Inner("soft reference test obj is alive."));
   slist.add(sr);
   //gargage collention 발생.
   System.gc();
   
   //gc 후 객체가 살아있는지 확인한다.
   for (SoftReference<Inner> refer : slist) {
    if (refer == null) {
     System.out.println("refer is null.");
    }else {
     Inner inner = refer.get();
     if (inner == null) {
      System.out.println("referenced obj is null.");
     }else
      System.out.println(inner.getStr());
    }
   }
  } catch (Exception e) {
    e.printStackTrace();
  }
}
}


위 코드는 간단한 테스트 코드로, 리스트에 일반적인 참조, WeakReference, SoftReference 로 add 한후, gc 를 실행시킨뒤 리스트에 객체에 대한 참조가 남아있는지 (생성한 객체가 gc 되었는지) 를 확인하는 코드이다.

실행시켜보면 다음과 같이 찍힌다.

simple reference is alive.
referenced obj is null.
soft reference test obj is alive.


WeakReference 로 참조한 객체만 gc 되서 null 이 찍힌다. jdk 버전등에 따라 결과가 다를 수도 있겠지만, 테스트코드만 돌리는 상황이라면 메모리 여유공간은 아마 넉넉할 것이므로, 대체로 같은 결과일 것이다.

출처 : http://jaguarmk.tistory.com/25

 

블로그 이미지

가카리

프로그래밍, 취업 및 직장생활, 주식 부동산 재테크 전문 블로그

댓글을 달아 주세요