장쫄깃 기술블로그

[Java] 참조 유형 (Strong Reference / Soft Reference / Weak Reference / Phantom Reference) 본문

Programming Language/Java

[Java] 참조 유형 (Strong Reference / Soft Reference / Weak Reference / Phantom Reference)

장쫄깃 2022. 6. 6. 01:00
728x90


들어가며


Java Strong Reference / Soft Reference / Weak Reference / Phantom Reference

 

Java의 참조 유형에는 크게 4가지가 있다.

참조 유형에 따라 GC 실행 대상 여부, 시점이 달라진다.

 

  1. Strong Reference (강한 참조)
  2. Soft Reference (소프트 참조)
  3. Weak Reference (약한 참조)
  4. Phantom Reference (팬텀 참조)

 

아래로 갈수록 GC의 대상이 되는 경우와 실행되는 시점이 앞당겨진다.

 

 

1. Strong References (강한 참조)


Java의 기본 참조 유형이다.

MyClass obj = new MyClass();

 

obj 변수가 참조를 가지고 있는 한, MyClass 객체는 GC의 대상이 되지 않는다.

 

 

 

2. Soft Reference (소프트 참조)


MyClass ref = new MyClass();      

SoftReference<MyClass> softRef = new SoftReference<MyClass>(ref); 

// 이 시점에 GC의 실행 대상이 가능 
ref = null;

// JVM의 메모리가 부족하지 않아 GC 실행 대상이 되지 않은 경우
// null이 반환되지 않고 기존 객체가 반환됨
ref = softRef.get();

 

대상 객체를 참조하는 경우가 SoftReference 객체만 존재하는 경우 GC의 대상이 된다.

단, JVM 메모리가 부족한 경우에만 힙 영역에서 제거되고 메모리가 부족하지 않다면 굳이 제거하지 않는다.

 

 

 

3. Weak Reference (약한 참조)


MyClass ref = new MyClass();      

WeakReference<MyClass> weakRef = new WeakReference<MyClass>(ref); 

// 이 시점에 GC의 실행 대상이 가능 
ref = null;

// 다음 GC 실행시 무조건 힙 메모리에서 제거
// 제거된 경우 null 반환
ref = softRef.get();

 

대상 객체를 참조하는 경우가 WeakReference 객체만 존재하는 경우 GC의 대상이 된다.

다음 GC 실행 시 무조건 힙 메모리에서 제거된다.

 

(톰캣 컨테이너의 ConcurrentCache Class에서 WeakHashMap을 사용 중)

 

 

 

4. Phantom Reference (팬텀 참조)


@Test
public void test() {
    MyClass ref = new MyClass();

    ReferenceQueue<MyClass> refQueue = new ReferenceQueue<MyClass>();

    PhantomReference<MyClass> phantomRef = null;
    // 팬텀 참조는 아래처럼만 생성이 가능하다
    phantomRef = new PhantomReference<MyClass>(ref,refQueue);

    ref = null;

    System.gc();

    // 예상 : true
    // 실제 테스트: false
    System.out.println(phantomRef.isEnqueued());

    System.out.println(phantomRef.get()); // null

}

 

생성자에서 무조건 ReferenceQueue를 받는다. (GC가 실행되기 전에 (finalize() 호출 후))

PhantomReference는 객체 내부의 참조를 null로 설정하지 않고 참조된 객체를 phantomly reachable 객체로 만든 이후에 ReferenceQueue에 enqueue 된다.

 

잘 쓰이지 않는다.

 


참고

https://lion-king.tistory.com/entry/Java-%EC%B0%B8%EC%A1%B0-%EC%9C%A0%ED%98%95-Strong-Reference-Soft-Reference-Weak-Reference-Phantom-References

728x90