Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на C / C++ / C++ for real programmers.pdf
Скачиваний:
262
Добавлен:
02.05.2014
Размер:
2.04 Mб
Скачать

251

}

// Иначе перемещение уже состоялось

}

}

Оптимизация

Только что описанный алгоритм способен резко тормозить программу при каждом запуске функции Scavenge(). Для оптимизации по отдельности или вместе могут использоваться два следующих подхода:

1. Функция Scavenge() работает поэтапно, а не как единая операция. Для этого вам придется модифицировать Copy1(), чтобы ее последовательный аналог вызывался до завершения сборки мусора.

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

Вряд ли эти варианты оптимизации стоит применять в реальных проектах — особенно второй, поскольку ведение списков потребует значительно больших затрат памяти и быстродействия.

Внешние объекты

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

1. Каждый внешний объект также должен обладать средствами перебора указателей и соблюдать правило «дескрипторы повсюду», по крайней мере для ссылок на внутренние объекты.

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

3.Если объект в функции Copy1() является внешним и непомеченным, он помечается, а его итератор заносится в стек, но сам объект при этом не перемещается.

Множественные пространства

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

Сборка мусора и уплотнение на месте

Решения из предыдущей главы, которые помогли нам превратить схему «дескрипторы повсюду» в уплотнение на месте, можно применить и в данной схеме. Это позволит организовать сборку мусора на месте и обойтись без копирования объектов в памяти. Существуют два варианта этой схемы: с уплотнением и без. В обоих случаях используется алгоритм пометки и удаления — на первом проходе определяются доступные объекты, а на втором происходит сборка мусора и при необходимости — уплотнение. Алгоритм предполагает, что в класс VoidPtr добавлен специальный «бит пометки»:

1. Снять пометку со всех VoidPtr, отсутствующих в списке свободных указателей.

2.Пометить все VoidPtr с ненулевым счетчиком ссылок; то есть пометить объекты, доступные непосредственно из стека.