자바의 레퍼런스 클래스 사용 가이드라인
참조: http://www.ibm.com/developerworks/java/library/j-refs/
SoftReference, WeakReference, PhantomReference 클래스들이 Java2에 추가되기 전에는 오직 Strong Reference만 사용할 수 있었다.
Object obj = new Object();
여기서 obj는 힙에 저장되어 있는 개체를 참조한다. obj 레퍼런스가 존재하는한 가비지 컬렉터Garbage Collector는 저장소를 비우지 않을 것이다.
obj가 스코프를 벗어나거나 null이 될 때야 비로소 해당 객체를 참조하는 레퍼런스가 없다는 가정하에 gc의 대상이 된다. 하지만, gc의 대상이 된다고 해서 무조건 자원을 반납하는게 아니라는 것이다. 왜냐면, gc 알고리즘이 매우 다양하고 그 중에 몇몇 알고리즘은 나이 많고, 오래 산 객체들을 짧게 산 객체들 보다 덜 검사하는 경향이 있다. 따라서 gc에 의해 가용한 객체가 절대로 반환되지 않을 수도 있다. 만약에 gc가 객체 자원을 반납하는 것보다 먼저 프로그램이 종료를 하면 문제가 발생할 수 있다. 따라서, 기본적으로 gc의 대상이 된다고 해서 자원을 반드시 반납한다는 것을 절대로 보장할 수 없다.
이 정보는 레퍼런스 클래스를 분석할 때 중요하다. 비록 특정 문제에서 유용한 클래스들이기는 하지만, gc의 기본 특징 때문에 여러분이 생각하는 것 만큼 유용하지는 않을 것이다. Soft, Weak 그리고 Phantom 레퍼런스 객체들은 gc를 막지 않고 힙 객체를 참조하는 세 가지 방법을 제공한다.
- Strongly reachable: strong reference로 참조할 수 있는 객체
- Softly reachable: Strongly reachable 하진 않지만, soft reference로 참조할 수 있는 객체
- Weakly reachable: 생략.
- Phantomly reachable: 생략.
- Clear: 객체의 레퍼런스 필드를 null로 설정한다. and declaring the object in the heap that the reference class referred to as finalizable.
SoftReference 클래스
메모리를 지각하는Memory-sensitive 캐시에 대한 레퍼런스로 사용하는 클래스이다. JVM이 out-of-memory를 발생하기 직전에 비워버리는 레퍼런스로 객체를 참조한다. 중요한 건 gc가 동작할 때, Softly reachable한 객체는 자원을 해제 할 수도 있고 그렇지 않을 수도 있다는 것이다. 객체 자원 해제는 gc 알고리즘과 gc 가 작업을 하는 시점에 가용한 메모리 양과 관계가 있다.
WeakReference 클래스
WeakReference 클래스는 기본적인 맵핑canonicalized mappings에 대한 레퍼런스로 사용하는 클래스이다. 오래 살 필요가 없고 다시 생성하는 비용이 비싸지 않는 객체에 대한 레퍼런스로 유용하다. 중요한 것은 gc 가 발동하면, Weakly Reachable한 객체의 자원을 반납한다는 것이다. 하지만, weakly reachable 한 객체를 찾고 자원을 반납하기 까지는 gc가 몇 번 발동해야 할 것이다.
PhantomReference 클래스
PhantomReference 클래스는 수집 되기 직전에 어떤 일을 수행하고 싶을 때 사용한다. ReferenceQueue와 함께 사용해야 한다.
...나머지 생략...
- 위의 세 가지 레퍼런스가 소멸 되는 과정
- 위의 레퍼런스 클래스의 get()과 ReferenceQueue의 poll()을 사용한 gc 테스트
- Weak 레퍼런스 만들려면 기본 Strong References는 null로 설정해야 함
- Soft, Weak, Phantom 레퍼런스를 다시 생성하는 방법.(gc가 발동할 수 있다는 가정 하게 코딩 해야 함.)