Правило 7 эффективного Java: избегайте финализаторов

В этой удивительной книге автор Джош Блох упоминает:

"О, и еще одно: использование финализаторов серьезно снижает производительность. На моей машине время создания и уничтожения простого объекта составляет около 5,6 нс. Добавление финализатора увеличивает время до 2400 нс. Другими словами, создание и уничтожение объектов с финализаторами примерно в 430 раз медленнее».

Есть ли способ, которым мы можем удалить и возразить в java?
Я подумал, что мы можем просто позволить объектам выйти из области видимости или сбросить их до нуля.
Я собираюсь поэкспериментировать с этим на своей машине, идея кажется забавной, но я не уверен как удалить и возразить.


person EMM    schedule 15.10.2014    source источник
comment
Если у вас нет особой необходимости в финализаторе, вам не нужно его использовать.   -  person Dave Newton    schedule 15.10.2014
comment
проверьте здесь   -  person TheLostMind    schedule 15.10.2014
comment
@ Дэйв Да, ты прав. Я понимаю это и также вижу ответный комментарий Эрану ниже, но мне было интересно, как автору удалось рассчитать время между созданием и удалением. Кажется довольно ясным, что он говорит об удалении, а не о том, что объект подлежит удалению. Спасибо, что нашли время помочь мне.   -  person EMM    schedule 15.10.2014


Ответы (2)


Как только вы сделаете ссылочную переменную ссылкой на null (при условии, что последняя ссылка) и эта переменная выйдет за пределы своей области, тогда объект может быть удален со сборкой мусора в следующем цикле сборки мусора.

person Eng.Fouad    schedule 15.10.2014
comment
Привет! Спасибо за быстрый ответ. Мне было интересно, как я могу вычислить время между созданием и удалением b/c, сбрасывая его на ноль, просто сделать его подходящим, на самом деле он не удаляет его. - person EMM; 15.10.2014
comment
@mohit - На самом деле вам нужно сбросить все ссылки до нуля. Объект должен быть недостижимым (что происходит, когда он выходит за пределы области видимости и ссылки извлекаются из стека). - person TheLostMind; 15.10.2014
comment
@mohit Ничто не удаляет его, кроме JVM, и технически вы не можете контролировать, когда запускается GC. Вы можете предложить его запустить, и многие реализации делают его запуск, когда вы предлагаете. - person Dave Newton; 15.10.2014
comment
@mohit Попробуйте использовать профилировщик Java, такой как JProfiler или YourKit. - person Eng.Fouad; 15.10.2014

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

Если бы объект, давший такое обещание, был оставлен и просто прекратил бы свое существование, внешний объект продолжал бы делать то, о чем его просили, в ущерб всем остальным, даже если бы его действия больше не приносили никакой пользы. любой. Чтобы избежать этой ситуации, Java позволяет объектам запрашивать уведомление, когда GC замечает, что они кажутся заброшенными. Такие уведомления будут даны (т.е. Finalize будет вызываться для таких объектов) до того, как объекты перестанут существовать, но кроме этого нет реальной гарантии своевременности. Завершенный объект может затем уведомить всех без исключения субъектов, действующих от его имени, о том, что они должны прекратить это делать.

Создатели Java, возможно, ожидали, что финализаторы будут основным механизмом, с помощью которого объекты могут уведомлять внешние сущности о том, что их службы больше не требуются, но на самом деле финализаторы работают не очень хорошо. Другие механизмы, такие как AutoCloseable или PhantomReference, во многих случаях лучше.

person supercat    schedule 15.10.2014