Как определить, когда объект больше не упоминается

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

Примером может служить объект, который поддерживается физическим файлом данных, и как только на объект перестают ссылаться, файл следует закрыть, а затем переименовать. Было бы хорошо, если бы это было возможно без явного вызова метода «close» для этого объекта.

Все механизмы уведомления, о которых я знаю из справочной области Weak / Phantom, говорят только о том, что уведомление произойдет в какой-то момент времени, но нет гарантии, когда это произойдет ...

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
9
0
3 104
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Ответ принят как подходящий

Короче нет.

Спецификация Java явно запрещает вам знать, когда была выпущена последняя ссылка. Реализации JVM (и оптимизации) зависят от этого. Крюка нет.

Не могли бы вы сослаться на спецификацию?

searchengine27 04.09.2015 03:54

Насколько я понимаю, и я некоторое время искал "деструктор" для объектов Java, нет никакого способа узнать, когда вы потеряете последнюю ссылку. Java отслеживает ссылки на объекты, но из соображений производительности обновляет эту информацию только во время сборки мусора.

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

Проблема в том, «Как это реализовать, если что-то не содержит ссылки на объект?»

Даже если вы могли бы решить эту проблему, скажем, с помощью службы, которую мы вызовем HandleManager, HandleManager затем должен был бы создать новую ссылку на объект для передачи вашему обработчику. Затем ваш обработчик мог либо (а) сохранить ссылку на него, что сбило бы с толку HandleManager, который ожидал уничтожить объект, на который нет ссылки; или (b) освободить ссылку, что означает, что последняя ссылка была снова освобождена, что означает, что Обработчик должен быть вызван снова ....

Вы мог переопределяете finalize() в своем объекте, но это проблематично по причинам, упомянутым другими.

В вашем конкретном примере вы можете использовать что-то вроде File.deleteOnExit(), которое удалит файл после выхода из виртуальной машины.

Этого нельзя сделать с Java - насколько я могу судить, ему нужен сборщик мусора, подсчитывающий ссылки. Рассматривали ли вы возможность открытия и закрытия файла физических данных вашего объекта по мере необходимости, вместо того, чтобы держать его открытым в течение всего времени существования объекта?

То, что вы описываете, является возможным обходным путем. Было бы неплохо, если бы был способ реализовать такие чистки таким образом, чтобы они вызывались, когда это необходимо. Однако это требует, чтобы клиенты объекта не забывали о явной очистке. Возможный источник ошибки.

VoidPointer 17.10.2008 13:02

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

Смотрите мой ответ Зачем вообще реализовывать finalize ()?

Я думаю, WeakReference делает то, что вы хотите. WeakReference помещается в ReferenceQueue, как только становится недостижимым (т.е. все сильные ссылки исчезают).

См. Эту статью Итан Николас.

Если вас беспокоит, что некоторые ссылки не достигают ReferenceQueue при завершении работы, сохраните список всех созданных объектов (используя WeakReferences или PhantomReferences). Добавьте ловушку выключения, которая проверяет список на наличие невыполненных ссылок и выполняет любое действие, которое вам нужно.

Другие вопросы по теме