Как Boehm GC работает для программы на C? - PullRequest
14 голосов
/ 25 января 2011

Я проверил Boehm GC. GC для C / C ++.

Я знаю алгоритм метки и развертки. Что мне интересно, так это то, что он собирает только указатели во всей C-памяти. Мое понимание памяти C - это простой байтовый массив. Можно ли определить значение в памяти указателя или нет?

1 Ответ

18 голосов
/ 25 января 2011

Boehm GC - консервативный сборщик, что означает, что он предполагает, что все является указателем. Это означает, что он может найти ложные положительные ссылки, например, целое число, которое по совпадению имеет значение адреса в куче. В результате некоторые блоки могут оставаться в памяти дольше, чем с неконсервативным сборщиком.

Вот описание со страницы Бема :

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

  1. Подготовка Каждый объект имеет связанный бит метки. Очистить все отметки биты, указывающие, что все объекты потенциально недоступен.
  2. Отметить фазу Отмечает все объекты, которые могут быть доступны через цепочки указатели от переменных. Часто коллекционер не имеет реальной информации о расположении указателя переменные в куче, поэтому он просматривает все статические области данных, стеки и регистрируется как потенциально содержащий указатели. Любые битовые шаблоны, которые представлять адреса внутри кучи объекты, которыми управляет коллектор рассматривается как указатели. Если только клиент программа сделала макет объекта кучи информация, доступная для коллектор, любые найденные объекты кучи быть доступным из переменных снова сканируется аналогично.
  3. Фаза развертки Сканирует кучу на предмет недоступности и, следовательно, без отметки, объекты и возвращает их соответствующий бесплатный список для повторного использования. это на самом деле это не отдельная фаза; четное в неинкрементном режиме это операция обычно выполняется на спрос во время распределения, обнаруживает пустой свободный список. Таким образом фаза развертки очень вряд ли коснется страница, которая не была бы все равно тронут вскоре после этого.
  4. Фаза завершения Недостижимые объекты, которые были зарегистрированы для завершение поставлены в очередь на доработка вне коллектора.

Вам также следует знать, что для Boehm GC должен быть задан набор «корней», которые являются отправными точками для алгоритма разметки и развертки. Стек и регистры автоматически становятся корнями. Вам нужно явно добавить глобальные указатели в качестве корней.


РЕДАКТИРОВАТЬ: В комментариях были отмечены некоторые проблемы относительно консервативных коллекционеров в целом. Это правда, что целые числа, которые выглядят как указатели кучи для сборщика, могут привести к тому, что память не будет освобождена. Это не такая большая проблема, как вы думаете. Большинство скалярных целых чисел в программе используются для подсчета и размера и довольно малы (поэтому они не будут похожи на указатели кучи). В основном вы столкнетесь с проблемами с массивами, содержащими растровые изображения, строки, данные с плавающей запятой или что-то в этом роде. Boehm GC позволяет вам выделить блок с GC_MALLOC_ATOMIC, который указывает сборщику, что блок не будет содержать указателей. Если вы посмотрите в gc_typed.h , вы также найдете способы указать, какие части блока могут содержать указатели.

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

...