77

세 참조 클래스 간의 차이점을 설명하거나 (좋은 설명에 대한 링크를 게시 할 수 있습니까?) SoftReference>WeakReference>PhantomReference하지만 각 경우는 언제 사용합니까? WeakHashMap이있는 이유는 무엇입니까? SoftHashMap 또는 PhantomHashMap이 아닌 이유는 무엇입니까? Java 참조 클래스 이해 : SoftReference, WeakReference 및 PhantomReference

그리고 나는 다음과 같은 코드를 사용하는 경우

...

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이 null인지 확인해야합니까 (잘못되었지만 입니다). 급한 문제로 불편을 드려 죄송합니다.하지만이 Reference 클래스를 이해하는 데 문제가 있습니다 ... 감사합니다.

+0

'WeakHashMap'이 있지만 SoftHashMap 또는 PhantomHashMap 우수한 질문이없는 이유는 무엇입니까? –

답변

6

링크 : get 항상 팬텀 참조를 null를 반환으로

PhantomHashMaphttps://community.oracle.com/blogs/enicholas/2006/05/04/understanding-weak-references 아주 잘 작동하지 않을 것입니다.

캐시가 어렵기 때문에 SoftHashMap은 생각만큼 잘 작동하지 않을 수 있습니다. 그러나 Google의 수집 라이브러리에는 일반적인 참조 맵 구현이 포함되어 있습니다.

항상 getnull을 반환하는지 확인해야합니다. (참고로 Reference 참조 자체가 null이 아닌지 확인한다는 점에 유의하십시오.) 인턴 문자열의 경우에는 항상 그렇지만 항상 "똑똑"하려고하지는 않습니다.

+0

링크가 만료되었습니다. –

+0

@MehrajMalik 링크가 고정되었습니다. –

57

Java 라이브러리 documentation for the java.lang.ref package은 세 가지 명시 적 참조 유형의 감소하는 강도를 특징으로합니다.

호스트 프로세스의 메모리가 부족해질 때까지 참조 된 개체를 유지하려는 경우 SoftReference을 사용합니다. 콜렉터 에 메모리를 확보하려면이 필요하기 전까지는 오브젝트를 수집 할 수 없습니다. 느슨하게 말하자면, SoftReference 바인딩은 "더 이상 가질 수 없을 때까지 객체 고정"을 의미합니다.

대조적으로 참조 된 개체의 수명에 영향을 미치지 않으려면 WeakReference을 사용하십시오. 살아있을 때까지 참조 된 객체에 대해 이라는 별도의 어설 션을 만들고 싶을뿐입니다. 컬렉션에 대한 개체의 적합성은 바인딩 된 WeakReference의 존재 여부에 영향을받지 않습니다. 오브젝트 인스턴스에서 관련된 특성으로의 외부 맵핑과 같은 것 (관련된 오브젝트가 살아있는 한 특성 만 기록하면 됨)은 WeakReferenceWeakHashMap에 적합합니다.

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

예제 코드에서는 null 일 수있는 ref 참조 (또는 원하는 경우 "변수")가 아닙니다. 오히려 null 일 수있는 Reference#get()을 호출하여 얻은 값입니다. null 인 것으로 판명되면, 너무 늦었습니다. 여기의 Truong 법사 TÌNH에 의해 주석에 명시된 바와 같이 그것은 또한 언급되어야한다

final String val = ref.get(); 
if (null != val) 
{ 
    // "val" is now pinned strongly. 
} 
else 
{ 
    // "val" is already ready to be collected. 
} 
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()가 중요합니다.