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

Определение качественности высвечивает трудности, связанные со сборкой мусора для некоторых языков программирования, и соответствующие роли языка и его реализации. Почему, например, сборка мусора обычно неприменима для С++? Обычно приводимые причины связаны с культурой: в мире С каждый разработчик должен сам заботиться о своих "игрушках" (по словам Стефенсона); он просто не доверяет какому-либо автоматическому механизму управлять его делами. Но, если бы это было действительной причиной, а не апостериорным оправданием, среды С++ могли бы, как минимум, предложить сборку мусора как подключаемую возможность, но большинство реализаций этого не делают.

Действительная проблема лежит в структуре языка, а не в технологии компиляции или культурных традициях. Язык С++, следуя С, слабо типизирован; он предоставляет возможность преобразования типа, благодаря которой на объект одного типа можно ссылаться как на сущность другого типа. Конструкция:

(OTHER_TYPE) x

означает, что теперь x рассматривается как сущность типа OTHER_TYPE, связанного или несвязанного с истинным типом x. Хорошие книги по С++ предостерегают приложения от применения подобных конструкций. Но разработчикам компилятора деваться некуда, - они обязаны реализовать язык в соответствии с его определением. Теперь представьте следующий сценарий. Ссылка на объект какого-либо полезного типа, скажем NUCLEAR_SUBMARINE, временно приведена к типу integer. Сборщик мусора, работающий в этот момент, не видит ссылки, а видит только целое типа integer. Не находя других ссылок на объект, сборщик утилизирует подлодку. Когда, через некоторое время программа выполнит обратное преобразование целого в ссылку типа NUCLEAR_SUBMARINE, будет уже поздно, - подлодка уничтожена.

Для решения этой проблемы предлагались разные методы. Широкого применения они не получили из-за накладываемых ограничений. Язык Java может рассматриваться как язык семейства C++, в котором введены существенные ограничения на систему типов, вплоть до удаления множественного наследования и универсализации, чтобы сделать, наконец, возможной сборку мусора в мире программ, основанных на С.

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

<p>Основа сборки мусора</p>

Рассмотрим работу сборщика мусора.

Основной алгоритм включает две фазы: пометка и чистка. Фаза пометки, начиная с оригиналов, рекурсивно следует ссылкам, проходит активную часть структуры и помечает как достижимые все встреченные объекты. Фаза чистки обходит всю структуру объектов, утилизируя все не помеченные объекты и удаляя все пометки. (Об оригиналах см. раздел "Достижимые объекты в ОО-модели этой лекции.")

Как и в случае с подсчетом ссылок, объекты включают дополнительное поле, используемое здесь для пометки. Но требуемая для этого поля память незначительна, - достаточно одного бита для каждого объекта. Как будет видно при изучении динамического связывания, реализация ОО-возможностей требует, чтобы объект имел дополнительную внутреннюю информацию (например, тип). Эта информация обычно занимает одно или два слова в каждом объекте. Бит пометки может быть частью служебного слова, и не будет занимать дополнительную память.

<p>Сборка по принципу "все-или-ничего"</p>

Когда нужно приводить в действие сборщик мусора?

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

Эта техника может быть названа "все-или-ничего". Преимущество ее в том, что она не вызывает перегрузки пока достаточно памяти. Когда программа выходит за пределы достижимых ресурсов, в наказание вызывается сборщик мусора.

Перейти на страницу:

Похожие книги