Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык программирования JAVA.pdf
Скачиваний:
374
Добавлен:
02.05.2014
Размер:
2.57 Mб
Скачать

converted to PDF by BoJIoc

выполняемого в настоящий момент метода, когда не удается найти ссылку на него

посредством отслеживания полей и элементов массивов статических данных и переменных методов, и так далее. Объекты создаются оператором new, но соответствующего ему оператора delete не существует. После завершения работы с объектом вы просто перестаете ссылаться на него (изменяете его ссылку так, чтобы она указывала на другой объект или null) или возвращаетесь из метода, чтобы его локальные переменные перестали существовать и не указывали на объект. Когда ссылок на объект не остается нигде, за исключением других неиспользуемых объектов, данный объект может быть уничтожен сборщиком мусора. Мы пользуемся выражением может быть”, потому что память освобождается лишь в том случае, если ее недостаточно или если сборщик мусора захочет предотвратить ее нехватку.

Автоматическая сборка мусора означает, что вам никогда не придется беспокоиться о проблеме зависших ссылок” (dangling references). В тех системах, где предусмотрен прямой контроль за удалением, допускается освобождение объектов, на которые ссылаются другие объекты. В таком случае ссылка становится зависшей”, то есть она указывает на область памяти, которая в системе считается свободной. Эта свободнаяпамять может быть использована для создания нового объекта, и тогда зависшая ссылкабудет указывать на нечто совершенно отличное от того, что предполагалось в объекте. В

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

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

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

2.10.1. Метод finalize

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

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

// ...

}

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

converted to PDF by BoJIoc

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

Иногда может случиться так, что метод close не будет вызван, несмотря на то, что работа с объектом закончена. Возможно, вам уже приходилось сталкиваться с подобными случаями. Вы можете частично предотвратить утечку файлов”, включив в класс метод finalize, внутри которого вызывается close, — таким образом можно быть уверенным, что

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

public class ProcessFile { private Stream File;

public ProcessFile(String path) { File = new Stream(path);

}

// ...

public void close() {

if (File != null) { File.close(); File = null;

}

}

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

close();

}

}

Обратите внимание: метод close написан так, чтобы его можно было вызвать несколько раз. В противном случае, если бы метод close уже использовался ранее, то при вызове finalize происходила бы попытка повторного закрытия файла, что может привести к ошибкам.

Кроме того, в приведенном выше примере следует обратить внимание на то, что метод finalize вызывает super.finalize. Пусть это войдет у вас в привычку для всех методов finalize, которые вам придется писать. Если не использовать super.finalize, то работа вашего класса завершится нормально, но суперклассы, для которых не были выполнены необходимые завершающие действия, могут вызвать сбои. Помните, вызов super.finalize — это полезное правило, применяемое даже в том случае, если ваш класс не является расширением другого класса. Помимо того, что это послужит вам дополнительным напоминанием на будущее, вызов super.finalize в подобных ситуациях позволит в будущем породить класс, аналогичный Process File, от другого суперкласса и при этом не заботиться о переделке метода finalize.

В теле метода finalize может применяться конструкция try/catch для обработки исключений в вызываемых методах, но любые неперехваченные исключения, возникшие при выполнении метода finalize, игнорируются. Исключения подробно рассматриваются в главе 7.

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