| При таком компромиссном подходе для сборщика мусора необходимо будет ввести не только бинарные критерии полноты и качественности, но и критерий, называемый своевременность (timeliness). Его значением является интервал времени от момента, когда объект становится недостижимым, до момента его утилизации, причем важно как среднее значение времени, так и верхняя его граница. |
Определение качественности высвечивает трудности, связанные со сборкой мусора для некоторых языков программирования, и соответствующие роли языка и его реализации. Почему, например, сборка мусора обычно неприменима для С++? Обычно приводимые причины связаны с культурой: в мире С каждый разработчик должен сам заботиться о своих "игрушках" (по словам Стефенсона); он просто не доверяет какому-либо автоматическому механизму управлять его делами. Но, если бы это было действительной причиной, а не апостериорным оправданием, среды С++ могли бы, как минимум, предложить сборку мусора как подключаемую возможность, но большинство реализаций этого не делают.
Действительная проблема лежит в структуре языка, а не в технологии компиляции или культурных традициях. Язык С++, следуя С, слабо типизирован; он предоставляет возможность преобразования типа, благодаря которой на объект одного типа можно ссылаться как на сущность другого типа. Конструкция:
(OTHER_TYPE) x
означает, что теперь
Для решения этой проблемы предлагались разные методы. Широкого применения они не получили из-за накладываемых ограничений. Язык Java может рассматриваться как язык семейства C++, в котором введены существенные ограничения на систему типов, вплоть до удаления множественного наследования и универсализации, чтобы сделать, наконец, возможной сборку мусора в мире программ, основанных на С.
При тщательно спроектированной системе типов, конечно, можно сочетать мощь множественного наследования и универсализации с безопасностью типов и поддержкой эффективной сборки мусора.
Основа сборки мусора
Рассмотрим работу сборщика мусора.
Основной алгоритм включает две фазы: пометка и чистка. Фаза пометки, начиная с оригиналов, рекурсивно следует ссылкам, проходит активную часть структуры и помечает как достижимые все встреченные объекты. Фаза чистки обходит всю структуру объектов, утилизируя все не помеченные объекты и удаляя все пометки. (Об оригиналах см. раздел "Достижимые объекты в ОО-модели этой лекции.")
Как и в случае с подсчетом ссылок, объекты включают дополнительное поле, используемое здесь для пометки. Но требуемая для этого поля память незначительна, - достаточно одного бита для каждого объекта. Как будет видно при изучении динамического связывания, реализация ОО-возможностей требует, чтобы объект имел дополнительную внутреннюю информацию (например, тип). Эта информация обычно занимает одно или два слова в каждом объекте. Бит пометки может быть частью служебного слова, и не будет занимать дополнительную память.
Сборка по принципу "все-или-ничего"
Когда нужно приводить в действие сборщик мусора?
Классические сборщики мусора активизируются по требованию и работают до завершения. Другими словами, сборщик мусора не работает, пока остается память для работы приложения. Как только ее не хватает, приложение запускает полный цикл сборки мусора - фаза пометки и следом фаза чистки.
Эта техника может быть названа "все-или-ничего". Преимущество ее в том, что она не вызывает перегрузки пока достаточно памяти. Когда программа выходит за пределы достижимых ресурсов, в наказание вызывается сборщик мусора.