Какова связь между 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());
Над двумя утверждениями печатается ноль. Если pr.get() возвращает null, означает ли это, что объект, на который ссылается pr, является сборщиком мусора? Если это так, то почему объект еще не добавлен в очередь приоритетов?
Кто-нибудь может помочь, пожалуйста, мне уточнить это. Я извиняюсь от вас, если мое понимание неверно в отношении PhantomReference и ReferenceQueue.
Пожалуйста, опишите эти два термина просто
большое спасибо
1 ответ
PhantomReference#get()
всегда возвращается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