2008-10-16 3 views
9

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

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

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

ответ

13

Короче , нет.

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

+0

Не могли бы вы ссылаться на спецификацию? – searchengine27 2015-09-04 00:54:16

4

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

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

2

Проблема заключается в следующем: «Как вы реализуете это, не имея ссылки на объект?»

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

-1

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

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

0

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

+0

То, что вы описали, - это возможное обходное решение. Было бы неплохо, если бы был способ реализовать такие очистки таким образом, чтобы их вызывали, когда это необходимо. Тем не менее, это требует, чтобы клиенты объекта помнили о явной очистке. Возможный источник ошибки. – VoidPointer 2008-10-17 09:02:35

2

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

Смотрите мой ответ Why would you ever implement finalize()?

3

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

См. Эту статью от Ethan Nicholas.

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

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