// Принудительная сборка мусора и финализация System gc().
}
} /* Output
Ошибка checkedOut
* ///•-
«Условие готовности» состоит в том, что все объекты Book должны быть «сняты с учета» перед предоставлением их в распоряжение сборщика мусора, но в методе main() программист ошибся и не отметил один из объектов Book. Если бы в методе finalize() не было проверки на условие «готовности», такую оплошность было бы очень сложно обнаружить.
Заметьте, что для проведения принудительной финализации был использован метод System.gc(). Но даже если бы его не было, с высокой степенью вероятности можно сказать, что «утерянный» объект Book рано или поздно будет обнаружен в процессе исполнения программы (в этом случае предполагается, что программе будет выделено столько памяти, сколько нужно, чтобы сборщик мусора приступил к своим обязанностям).
Обычно следует считать, что версия finalize() базового класса делает что-то важное, и вызывать ее в синтаксисе super, как показано в Book.finalize(). В данном примере вызов закомментирован, потому что он требует обработки исключений, а эта тема нами еще не рассматривалась.
Как работает сборщик мусора
Если ранее вы работали на языке программирования, в котором выделение места для объектов в куче было связано с большими издержками, то вы можете предположить, что и в Java механизм выделения памяти из кучи для всех данных (за исключением примитивов) также обходится слишком дорого. Однако в действительности использование сборщика мусора дает немалый эффект по
Представтьте кучу языка С++ в виде лужайки, где каждый объект «застолбил» свой собственный участок. Позднее площадка освобождается для повторного использования. В некоторых виртуальных машинах Java куча выглядит совсем иначе; она скорее похоже на ленту конвейера, которая передвигается вперед при создании нового объекта. А это значит, что скорость выделения хранилища для объекта оказывается весьма высокой. «Указатель кучи» просто передвигается вперед в «невозделанную» территорию, и по эффективности этот процесс близок к выделению памяти в стеке С++. (Конечно, учет выделенного пространства сопряжен с небольшими издержками, но их никоим образом нельзя сравнить с затратами, возникающими при поиске свободного блока в памяти.)
Конечно, использование кучи в режиме «ленты конвейера» не может продолжаться бесконечно, и рано или поздно память станет сильно фрагментиро-вана (что заметно снижает производительность), а затем и вовсе исчерпается. Как раз здесь в действие вступает сборщик мусора; во время своей работы он компактно размещает объекты кучи, как бы смещая «указатель кучи» ближе к началу «ленты», тем самым предотвращая фрагментацию памяти. Сборщик мусора реструктуризует внутреннее расположение объектов в памяти и позволит получить высокоскоростную модель кучи для резервирования памяти.
Чтобы понять, как работает сборка мусора в Java, необходимо узнать, как устроены реализации сборщиков мусора (СМ) в других системах. Простой, но медленный механизм СМ называется