2016-12-30 7 views
1

Java позволяют написать:PhantomReference с очередью нулевой

new PhantomReference(new Object(), null) 

В этом случае new Object() будет собираться?

Как я понимаю, фантомное обращение является альтернативой finalize() способ использования.

И после появления ссылок в очереди, мне нужно сделать некоторые дополнительные действия, а затем запустить clear()

Java документа остается:

Можно создать ссылку фантомной с нулевой очередью, но такая ссылка совершенно бесполезна: его метод прибудет будет всегда возвращение утратившим, поскольку он не имеет очередей, он никогда не будет помещён

Что значит, если он никогда не будет выставлен в очередь?

Как я понимаю, это означает, что после завершения вызова метода обращение не будет добавлено в referenceQueue. Таким образом, это может привести к:
1. памяти объекта будут удалены сразу
2. памяти объекта не будет очищен

тогда правильно?

+1

Каков ваш реальный вопрос здесь? Можете ли вы объяснить свою проблему более четко? – UNIQUEorn

+0

Вы посмотрели на это http://stackoverflow.com/questions/1599069/have-you-ever-used-phantom-reference-in-any-project, например? – GhostCat

+0

И javadoc для этого PhantomReference ctor ясно говорит: * Можно создать фантомную ссылку с нулевой очередью, но такая ссылка абсолютно бесполезна: метод get всегда будет возвращать null и, поскольку у него нет очереди, он никогда не будет выставлен в очередь. * Итак, да, этот вновь созданный Объект, таким образом, подвергается сбору мусора. – GhostCat

ответ

2

Ну, как вы заметили себя, PhantomReference не будет автоматически очищаться. Это подразумевает, что до тех пор, пока вы будете хорошо ссылаться на PhantomReference, референт останется доступным для фантома. Поскольку documentation говорит: «Объект, доступный с помощью фантомных ссылок, останется таким, пока все такие ссылки не будут очищены или сами не станут недоступными. "

Однако, учитывая, что объект недоступен (теперь я говорю о самих« фантомных ссылках »), это может привести ко многим неожиданностям. Тем более, что очень вероятно, что ссылочный объект, не обеспечивающий полезных операций, больше не будет затронут.

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

Так почему же конструктор позволяет построить такой бесполезный объект? Ну, the documentation of the very first version (1.2) заявляет, что он выкинет NullPointerException, если очередь null. Это заявление сохраняется до 1.4, затем Java 5 - это первая версия, содержащая утверждение, что вы можете построить PhantomReference без очереди, несмотря на то, что они бесполезны. Я предполагаю, что он всегда унаследовал поведение суперкласса, разрешающего очередь null, что противоречило документации, и было замечено так поздно, что было принято решение оставаться совместимым и адаптировать документацию, а не изменять поведение.


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

Этот вопрос был brought up on SO, но ответ действительно не удовлетворяет. В нем говорится: «Разрешить выполнять очистку до, объект представляет собой сбор мусора», что может даже соответствовать мышлению того, кто принял это дизайнерское решение, но поскольку код очистки не может получить доступ к объекту, он не имеет никакого отношения к тому, выполняется ли оно до или после восстановления объекта. Как было сказано выше, поскольку это правило зависит от достижимости объекта PhantomReference, который может быть оптимизирован для преобразования кода, может быть даже тот случай, когда объект будет восстановлен вместе с экземпляром PhantomReference до того, как код очистки будет завершен, без каких-либо замечаний.

Я также нашел аналогичный question on the HotSpot developer mailing list еще в 2013 году, который также не имеет ответа.

Существует запрос повышение JDK-8071507, чтобы изменить это поведение и четкие PhantomReference точно так же как другие, который имеет статус «фиксированный» для Java 9, и в самом деле, its documentation Теперь говорится, что они очищаются, как и любой другой ссылки.

Это, к сожалению, подразумевает, что ответ в начале моего сообщения будет неправильным, начиная с Java 9. Затем new PhantomReference(new Object(), null) сделает вновь созданный экземпляр Object немедленно подходящим для сбора мусора, независимо от того, сохраняете ли вы сильную ссылку на пример PhantomReference.

+0

хорошие исследования. Таким образом, поскольку java 9 PhantomReference не будет завершать альтернативу (потому что семантический «до очистки») будет нарушен? как насчет обратной совместимости? – gstackoverflow

+0

Как я и пытался сказать, семантика «до освобождения» никогда не использовалась. Ссылка на фантом никогда не позволяет получить доступ к референту, следовательно, не имеет значения, сохраняется ли референт в памяти или нет. Хранение его в памяти дольше, чем необходимо, было пустой тратой ресурсов. Вот почему несколько приложений (включая мои) всегда использовали «WeakReference» вместо этого, что устраняет необходимость в сборе референта в два раза, что потенциально более эффективно. Для объектов без пользовательского метода 'finalize()' семантической разницы нет. Начиная с Java 9, различия еще меньше. – Holger

Смежные вопросы