Java의 참조 클래스 이해 : SoftReference, WeakReference 및 PhantomReference


81

누군가가 세 가지 참조 클래스의 차이점을 설명 할 수 있습니까 (또는 멋진 설명에 대한 링크를 게시 할 수 있습니까)? SoftReference> WeakReference> PhantomReference하지만, 나는 각각을 사용하는 경우? 또는 WeakHashMap없는 이유는 무엇 입니까?SoftHashMapPhantomHashMap

그리고 다음 코드를 사용하면 ...

WeakReference<String> ref = new WeakReference<String>("Hello!");
if (ref != null) {                 // ref can get collected at any time...
    System.gc();                   // Let's assume ref gets collected here.
    System.out.println(ref.get()); // Now what?!
}

...무슨 일이야? 내가 있는지 확인해야합니까 ref마다 문 앞에 널 (이것은 잘못된 것입니다,하지만 해야합니다 내가 할)? 빠른 질문에 대해 죄송합니다.이 Reference수업을 이해하는 데 문제가 있습니다 ... 감사합니다!


1
질문이 WeakHashMap없는데 SoftHashMap또는 PhantomHashMap우수 질문 이있는 이유는 무엇입니까 ?
Mehraj Malik 2017

1
ref != null검사는 이해되지 않는다. ref결코 될 것 null입니다.
Holger

Q : strongRef --> weakRef --> objA. 이제에서 objA간접 참조가 있기 때문에 GCed 여부 가 결정 됩니다 strongRef.
samshers

답변:


60

패키지에 대한java.lang.ref Java 라이브러리 문서 는 세 가지 명시 적 참조 유형의 감소하는 강도를 특징으로합니다.

당신은을 사용하여 SoftReference호스트 프로세스가 메모리가 부족 실행 될 때까지 참조 된 개체가 살아 남기 위해 할 때. 수집기 메모리를 해제 해야 할 때까지 개체를 수집 할 수 없습니다 . 느슨하게 SoftReference말하면 바인딩은 "더 이상 할 수 없을 때까지 개체를 고정합니다."라는 의미입니다.

반대로, WeakReference참조 된 객체의 수명에 영향을주지 않으려면 a를 사용하십시오 . 참조 된 개체가 살아있는 한, 참조 된 개체 에 대해 별도의 주장을하기를 원할뿐입니다 . 수집에 대한 객체의 적격성은 bound WeakReference의 존재에 의해 영향을받지 않습니다 . 객체 인스턴스에서 관련 속성으로의 외부 매핑과 같은 것인데, 관련 객체가 살아있는 동안 만 속성을 기록해야하는 경우 WeakReferences 및 WeakHashMap.

마지막 PhantomReference것은 특성화하기가 더 어렵습니다. 와 같이 WeakReference이러한 경계 PhantomReference는 참조 된 객체의 수명에 영향을주지 않습니다. 그러나 다른 참조 유형과 달리 PhantomReference. 어떤 의미에서는 발신자가 말할 수있는 한 그것이 가리키는 것을 가리 키지 않습니다. 단지 일부 관련 데이터를 참조 된 객체와 연관시킬 수 있습니다.이 데이터는 나중에 검사하고 PhantomReference관련에서 대기열에 추가 될 때 조치를 취할 수 있습니다 ReferenceQueue. 일반적으로 하나는 유형을 파생하고 PhantomReference해당 파생 유형에 몇 가지 추가 데이터를 포함합니다. 불행히도 이러한 파생 유형을 사용하기 위해 몇 가지 다운 캐스팅이 필요합니다.

예제 코드에서 refnull 일 수있는 것은 참조 (또는 원하는 경우 "변수")가 아닙니다 . 오히려 Reference#get()null 일 수있는 호출로 얻은 값 입니다. null 인 것으로 확인되면 너무 늦습니다. 참조 된 객체가 이미 수집 중입니다.

final String val = ref.get();
if (null != val)
{
  // "val" is now pinned strongly.
}
else
{
  // "val" is already ready to be collected.
}

Q : strongRef --> weakRef --> objA. 이제에서 objA간접 참조가 있기 때문에 GCed 여부 가 결정 됩니다 strongRef.
samshers

귀하의 질문을 올바르게 이해하면 @samshers objA는 쓰레기 수거 대상입니다. 를 고정 WeakReference해도 해당 WeakReference지점 이 가리키는 개체에 영향을주지 않습니다 .
seh

체인에 강한 참조가 없으면 차이가 있습니다. 위해 때문에 objA될 가비지 수집 약한 참조 갖는 제 권리를 제거한다. 강력한 참조는 약한 참조를 가리키고있어 약한 참조는 GCed가 될 수 없습니다
samshers

아니요, WeakReference수집을 허용하기 위해 수집 할 필요는 없습니다 objA. 은 WeakReference유지하지 않습니다 objA살아. 그보다는 objA수명에 영향을주지 않고 살아있는 동안 을 찾고 수집가가 이미 가져간시기를 감지하는 방법입니다.
seh

6

링크 : https://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references

PhantomHashMap팬텀 참조에 대해 get항상 반환 null되는 것처럼 잘 작동하지 않습니다 .

캐시는 어렵 기 때문에 SoftHashMap생각만큼 제대로 작동하지 않을 수 있습니다. 그러나 Google의 컬렉션 라이브러리에는 일반적인 참조 맵 구현이 포함되어 있다고 생각합니다.

항상 getnon- 을 반환 하는지 확인해야 합니다 null. ( Reference참조 자체가 아닌지 확인하지 않습니다 null.) 인턴 된 문자열의 경우 항상 그럴 것이지만 (그대로) 그것에 대해 "영리"하려고하지 마십시오.


링크가 만료되었습니다.
Mehraj Malik 2017

@MehrajMalik Link가 수정되었습니다.
톰 Hawtin의 - tackline

Q : strongRef --> weakRef --> objA. 이제에서 objA간접 참조가 있기 때문에 GCed 여부 가 결정 됩니다 strongRef.
samshers


0
String str = new String("hello, world");
WeakReference<String> ref = new WeakReference<String>(str);
str = null;

if (ref != null) {                 
    System.gc(); 
    System.out.println(ref.get());
}

이 경우 null을 출력합니다. System.gc()여기에서에 대한 호출 이 중요합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.