이펙티브 자바를 읽다가 약한참조에 대한 이야기가 나와서 포스팅한다.
참조에는 아래 4가지가 존재한다.
- Strong References (강한 참조)
- Soft References (소프트 참조)
- Weak References (약한 참조)
- Phantom References (팬텀 참조)
이 해당 참조 유형에 따라 GC 실행 대상여부, 시점이 달라진다.
강한참조
new 연산자를 사용하여 객체를 인스턴스화 하고 참조하는 방식.
참조가 해제되지 않으면 GC의 대상이 되지 않는다.
Test test = new Test();
해당 test라는 변수가 참조를 가지고 있다면 GC의 대상이 되지 않는다.
test = null이 되는 순간 GC의 대상이 된다.
소프트참조
대상 객체의 참조가 SoftReference만 있다면 GC의 대상이 된다.
단, JVM 메모리가 부족한 경우에만 Heap에서 제거된다.
메모리가 부족하지 않은경우에는 제거하지 않는다.
public static void main(String[] args) {
String ss = "문자열";
SoftReference<String> reference = new SoftReference<>(ss);
// 이 시점에 GC의 실행 대상이 가능
ss = null;
System.gc();
// JVM의 메모리가 부족하지 않아서 GC 실행 대상이 되지 않은 경우
// 그대로 유지한다.
ss = reference.get();
System.out.println(ss);
}
약한참조
위에서 봤던 소프트참조와 비슷하게
대상 객체의 참조가 WeakReference만 있다면 GC의 대상이 된다.
다른점은, 메모리가 부족한경우가 아니라 다음 GC가 일어나게 되면 바로 힙에서 제거된다.
public static void main(String[] args) {
String ss = "문자열";
WeakReference<String> reference = new WeakReference<>(ss);
// 이 시점에 GC의 실행 대상이 가능
ss = null;
System.gc();
// gc를 명시적으로 호출했지만 컬렉션이 동작하지 않을수도 있음
// 그래도 무조건 동작한다고 가정
ss = reference.get();
// null 로 비어있게 된다.
System.out.println(ss);
}
팬텀참조
생성시 ReferenceQueue가 필요하며, PhantomReference의 참조값을 수동으로 clear() 메서드를 실행해야 하고, PhantomReference.get() 메서드는 항상 null을 반환한다는 특징이 있다.
PhantomReference는 객체 내부의 참조를 null로 설정하지 않고 참조된 객체를 phantomly reachable 객체로 만든 이후에 ReferenceQueue에 enqueue 된다.
두가지에서 사용한다.
- 자원 정리 (finalizer 보다는 조금 나은 방법) 그렇지만 try-with-resources를 사용하자.
- 생성 비용이 비싼 객체가 언제 메모리에서 해제되는지 알 수 있음.
'Java' 카테고리의 다른 글
effectively final 및 lambda capturing에 대해 톺아보기 (2) | 2023.12.08 |
---|---|
Checked Exception, Unchecked Exception (0) | 2022.09.07 |
변성 (0) | 2022.08.11 |
일급 컬렉션 (0) | 2022.08.09 |