Что делает финализаторы такими дорогими?

Из эффективной Java:

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

Что делает финализаторы такими дорогими?


person Geek    schedule 17.07.2012    source источник
comment
Ничего себе, если вы сокращаете наносекунду вдвое, вам, вероятно, не следует использовать Java, но рассмотрите язык, который ближе к металлу :-)   -  person Darin Dimitrov    schedule 17.07.2012
comment
0,00000024 секунды - это не так уж много. Если вы собираетесь пройти через это миллион раз, то это может быть 2 секунды.   -  person alexyorke    schedule 17.07.2012
comment
Кстати, в методе finalize() вы можете снова оживить объект. например добавив его в коллекцию. :П   -  person Peter Lawrey    schedule 17.07.2012
comment
Повторяющийся вопрос... stackoverflow.com/questions/2860121/   -  person Flavio    schedule 17.07.2012
comment
@ alexy13 alexy13, возможно, миллион таких объектов приводит к 2-секундной задержке; однако, если вы часто просматриваете эти объекты, то без использования финализаторов вы сможете пройти через 430 из этих объектов. Без четкого понимания роли Объекта не стоит беспокоиться об этом. Возможно, они являются переходными процессами при вычислении довольно большой матрицы, и в этом случае ускорение в 430 раз будет означать, что можно будет обрабатывать гораздо большие матрицы. Да, в целом вы правы, но всегда есть исключения.   -  person Edwin Buck    schedule 17.07.2012
comment
@ Эдвин, я согласен. Это также зависит от машины, на которой тестировался финализатор. Может быть, современные компьютеры настолько быстры, что стали намного меньше (не уверен). У меня нет большого опыта в языке программирования Java, поэтому я, вероятно, не должен делать предположений.   -  person alexyorke    schedule 17.07.2012


Ответы (3)


http://www.ibm.com/developerworks/java/library/j-jtp01274/index.html

выдержка из ссылки выше

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

person nate_weldon    schedule 17.07.2012

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

Разница наиболее заметна в молодом поколении сборщика мусора: в оптимистичном и не совсем редком сценарии сборщик мусора сводится к одной операции: уменьшению указателя на первый доступный адрес памяти. С финализаторами весь процесс описан выше.

person Marko Topolnik    schedule 17.07.2012
comment
Вероятно, вам нужно перефразировать. Решающее отличие заключается в самом существовании метода финализатора, т.к. Решающее отличие заключается в самом существовании нетривиального метода финализатора, поскольку у каждого объекта есть метод finalize(). - person Geek; 17.07.2012
comment
На самом деле, если я удалю метод слова, я буду в соответствии с JLS. Однако я оставил его там, потому что так он казался более очевидным. - person Marko Topolnik; 17.07.2012

Когда вы проводите бенчмаркинг, вы, вероятно, оцениваете срок полезного использования Объекта.

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

Это не на 100 %, потому что существует метод финализации, который добавляет так много времени, большая часть которого приходится на ожидание пробуждения потоков сборки мусора и, в конце концов, наткнуться на ваш отсоединенный объект (и решить, что-то с этим делать).

person Edwin Buck    schedule 17.07.2012