2014-10-08 3 views
1

자바에서 PhantomReference에 대해 약간의 혼란을 겪고 있습니다. 필자가 온라인 기사를 살펴본 결과, PhantomReference 객체가 참조에서 get()을 호출하고 PhantomReference 객체가 PhantomReference가 제거되었을 때 ReferenceQueue에 삽입된다는 사실을 언급하더라도 PhantomReference 객체가 생성 후 null을 반환한다고 언급했다. 기억.PhantomReference와 ReferenceQueue 사이의 관계는 무엇입니까?

다음 코드 예제를 시도했지만 그 결과에 혼란이 있습니다.

Equipment equipment = new Equipment(); 
ReferenceQueue queue = new ReferenceQueue(); 
PhantomReference pr = new PhantomReference(equipment, queue); 

System.out.println(pr.get()); 
System.out.println(queue.poll()); 

위의 두 명령문은 null을 출력합니다. pr.get()이 null을 반환하면 pr에 의해 참조 된 객체가 가비지 수집되는 것을 의미합니까? 그렇다면 개체가 여전히 우선 순위 큐에 추가되지 않은 이유는 무엇입니까?

누구든지이 문제를 명확히 설명 할 수 있습니까? PhantomReference와 ReferenceQueue에 대한 나의 이해가 잘못 되었다면 사과드립니다.

은 단순히뿐만 아니라

덕분에 많은

답변

2

PhantomReference#get()always returns null을이 두 용어를 설명해주십시오.

이 참조 객체의 참조 대상을 반환합니다. 팬텀 참조의 대상을 항상 액세스 할 수 없으므로이 메서드는 항상 null을 반환합니다.

get()을 통해 수집 여부를 알 수 없습니다.

그렇게이면 가비지 수집기가 특정 시점에서 결정하면 개체가 여전히 우선 순위 큐에

javadoc 상태

추가하지 않은 이유 그 팬텀 레퍼런스의 지시 대상은 팬텀 도달 가능, 그 다음에 시간 또는 나중에 참조를 대기열에 넣습니다. 시간 poll() (비 차단)에 의해 수집

따라서 인스턴스 중 하나가 없었다 쓰레기가 호출 또는 인스턴스는 가비지 수집되었지만, 대응 PhantomReferenceReferenceQueue는 첨가하지 않았다.

강력한 참조를 null으로 설정하고 GC를 요청할 때 대기열에서 removeReference으로 차단하여 도움을받을 수 있습니다.

equipment = null; 
System.out.println(pr.get()); 
System.gc(); 
System.out.println(queue.remove()); // block and wait for it to be added 
+0

답변을 주셔서 감사 드리며 상황을 명확하게 이해하는 데 도움이되었지만 System.gc()를 호출하는 이유를 알고 싶습니다. 그리고 나서 queue.remove()를 호출하십시오. 설명해 주시겠습니까 – Dilan

+0

@ user3115189'System.gc()'는 가능한 모든 것을 가비지 수집기로 가비지 수집기에 _suggestion_합니다. 가비지 수집되는 '장비'객체를 볼 기회가 더 많습니다. 대기열.remove()'는'poll()'대신에 호출된다. 왜냐하면 대기열에서 엔트리를 기다리는 것을 차단하기 때문이다. 내 대답은 javadoc에서 따옴표를 참조하십시오. 가상 참조는 ** ** 나중에 ** 대기열에 추가 될 수 있습니다. 우리는 그 일이 일어날 때까지 기다리고 싶다. –

+0

고맙습니다. – Dilan