Спецификация Java: пункт 12.6. Финализация экземпляров классов

У класса Object есть защищенный метод под названием finalize; этот метод может быть переопределен другими классами. Конкретное определение finalize, которое может быть вызвано для объекта, называется финализатором (finalizer) этого объекта. Прежде чем хранилище для объекта будет освобождено сборщиком мусора, виртуальная машина Java вызовет финализатор этого объекта.

Финализаторы предоставляют возможность освободить ресурсы, которые не могут быть освобождены автоматически автоматическим диспетчером хранения. В таких ситуациях простое освобождение памяти, используемой объектом, не гарантирует, что ресурсы, которые он удерживает, будут освобождены.

В языке программирования Java не указывается, как скоро будет вызван финализатор, за исключением того, что это произойдет до того, как хранилище для объекта будет повторно использовано.

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

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

Язык программирования Java не устанавливает порядок при вызовах методов finalize. Финализаторы могут вызываться в любом порядке или даже одновременно.

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

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

Гарантируется, что поток, вызывающий финализатор, не будет удерживать какие-либо видимые пользователем блокировки синхронизации при вызове финализатора.

Если во время финализации возникает неперехваченное исключение, исключение игнорируется и финализация этого объекта прекращается.

Завершение конструктора объекта происходит до (happens-before) выполнения его метода finalize (в формальном смысле происходит до).

Метод finalize, объявленный в классе Object, не выполняет никаких действий. Тот факт, что в классе Object объявляется метод finalize, означает, что метод finalize для любого класса всегда может вызвать метод finalize для своего суперкласса. Это нужно делать всегда, если только программист не намерен аннулировать действия финализатора в суперклассе. (В отличие от конструкторов, финализаторы не вызывают автоматически финализатор для суперкласса; такой вызов должен быть явно закодирован.)

Для эффективности реализация может отслеживать классы, которые не переопределяют метод finalize класса Object или не переопределяют его тривиальным способом.

Например:

protected void finalize() throws Throwable {
    super.finalize();
}

Поощряется реализациям рассматривать такие объекты как имеющие не замещаемый финализатор и более эффективно их финализировать.

Финализатор может быть вызван явно, как и любой другой метод.

Пакет java.lang.ref описывает слабые ссылки (weak references), которые взаимодействуют со сборкой мусора и финализацией. Как и в случае с любым API, который имеет особые взаимодействия с языком программирования Java, разработчики должны быть осведомлены обо всех требованиях, налагаемых API java.lang.ref.


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки