Какова связь между PhantomReference и ReferenceQueue?

У меня небольшая путаница по поводу PhantomReference в java. Когда я просматривал онлайн-статьи, большинство из них упомянули, что объект PhantomReference вернет значение null после создания, даже если мы вызовем get() для ссылки, а также упомянули, что объекты, фантомно доступные, будут вставлены в ReferenceQueue, когда PhantomReference будет удален из память.

Я пробовал следующий пример кода, но у меня есть путаница в результате.

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.

Пожалуйста, опишите эти два термина также просто

большое спасибо


person Dilan    schedule 08.10.2014    source источник


Ответы (1)


PhantomReference#get() всегда возвращает null.

Возвращает референт этого ссылочного объекта. Поскольку референт фантомной ссылки всегда недоступен, этот метод всегда возвращает значение null.

Вы не можете знать, было ли оно собрано или нет через get().

Если это так, то почему объект до сих пор не добавлен в приоритетную очередь

Состояние javadoc

Если сборщик мусора определяет в определенный момент времени, что референт фантомной ссылки является фантомно достижимым, тогда в это время или позже он поставит ссылку в очередь.

Таким образом, либо экземпляр не был собран мусором к моменту вызова poll() (неблокирующего), либо экземпляр был собран мусором, но соответствующий PhantomReference не был добавлен в ReferenceQueue.

Вы можете помочь ему, установив сильную ссылку на null и запросив GC, а также заблокировав remove Reference из очереди.

equipment = null;
System.out.println(pr.get());
System.gc();
System.out.println(queue.remove()); // block and wait for it to be added
person Sotirios Delimanolis    schedule 08.10.2014
comment
Спасибо за ваш ответ, и это помогло мне лучше понять контекст, но я хотел бы знать, почему вы вызываете System.gc(); а затем вызовите queue.remove(). Не могли бы вы объяснить это - person Dilan; 08.10.2014
comment
@ user3115189 System.gc() — это предложение сборщику мусора собрать все, что возможно. Это дает нам больше шансов увидеть объект Equipment сборщиком мусора. queue.remove() вызывается вместо poll(), потому что он блокирует ожидание появления записи в очереди. Смотрите цитату из javadoc в моем ответе. Фантомная ссылка может быть добавлена ​​в очередь позже. Мы хотим подождать, пока это не произойдет. - person Sotirios Delimanolis; 08.10.2014