Остерегайтесь методов flnalize

Методы finalize непредсказуемы, часто опасны и, как правило, не нужны. Их использование может привести к странному поведению программы, низкой производительности и проблемам с переносимостью. Метод finalize имеет лишь несколько областей применения (см. ниже), а главное правило таково: следует избегать методов finalize.

Программистов, пишущих на С++, следует предостеречь в том, что нельзя рассматривать методы finalize как аналог деструкторов в С++. В С++ деструктор _ это обычный способ утилизации ресурсов, связанных с объектом, обязательное дополнение к конструктору. В языке программирования java, когда объект становится недоступен, очистку связанной с ним памяти осуществляет сборщик мусора. Со стороны же программиста никаких специальных действий не требуется. В С++ деструкторы используются для освобождения не только памяти, но и других ресурсов системы. В языке программирования java для этого обычно применяется блок try-finally.

Нет гарантии, что метод finalize будут вызван немедленно [JLS, 12.6]. С момента, когда объект становится недосТупен, и до момента выполнения метода finalize может пройти сколь угодно длительное время. Это означает, что с помощьюметода finalize нельзя выполнять никаких операций, критичных по времени.Например, будет серьезной ошибкой ставить процедуру закрытия открытых файлов в зависимость от метода finalize, поскольку дескрипторы открытых файлов — ресурс ограниченный. Если из-за того, что jVM медлит с запуском методов finalize, открытыми будут оставаться много файлов, программа может завершиться с ошибкой, поскольку ей не удастся открыть новые файлы.

Частота запуска методов finalize в первую очередь определяется алгоритмом сборки мусора, который существенно меняется от одной реализации jVM к другой. Точно так же может меняться и поведение программы, работа которой зависит от частоты вызова методов finalize. Вполне возможно, что программа будет превосходно работать с jVM, на которой проводится ее тестирование, а затем позорно даст сбой на JVM, которую предпочитает ваш самый важный заказчик.

Запоздалый вызов методов finalize — не только теоретическая проблема. Создав ДЛЯ какого-либо класса метод finalize, в ряде случаев можно спровоцировать произвольную задержку при удалении его экземпляров. Один мой коллега недавно отлаживал приложение СИI, которое было рассчитано на длительное функционирование, но таинственно умирало с ошибкой OutOfMemoryError. Анализ показал, что в момент смерти приложение в очереди на удаление стояли тысячи графических объектов, ждавших лишь вызова метода finalize и утилизации. К несчастью, поток утилизации выполнялся с меньшим приоритетом, чем другой поток того же приложения, а потому удаление объектов не могло осуществиться в том же темпе, в каком они становились доступны для удаления. Спецификация языка Java не определяет, в каком из потоков

Остерегайтесь ЛУКА! ОПАСНОСТЬ, О КОТОРОЙ ВЫ НИКОГДА НЕ ЗНАЛИ… И ВОТ ПОЧЕМУ!


Читать еще…

Понравилась статья? Поделиться с друзьями: