Подтвердить что ты не робот

Сбор мусора против общих указателей

В чем различия между общими указателями (такими как boost:: shared_ptr или новый std:: shared_ptr) и методами сбора мусора (например, реализованными на Java или С#)? Как я понимаю, общие указатели отслеживают, сколько раз переменные указывают на ресурс, и автоматически уничтожит ресурс, когда счетчик достигнет нуля. Тем не менее, я понимаю, что сборщик мусора также управляет ресурсами памяти, но требует дополнительных ресурсов для определения того, относится ли объект к прежнему объекту и не обязательно немедленно уничтожает ресурс.

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

4b9b3361

Ответ 1

Основное различие заключается, как вы отметили, в том, когда ресурс освобожден/уничтожен.

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

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

Ответ 2

Эти общие указатели (обычно называемые подсчетами ссылок) управляют риском циклов.

У мусора (Mark and Sweep) нет этой проблемы.

Ответ 3

В простой сборке мусора никто не будет прятать прямой указатель на любой объект; вместо этого код будет содержать ссылки на записи в таблице, которые указывают на объекты в куче. Каждый объект в куче будет хранить свой размер (что означает, что все объекты кучи образуют односвязный список) и обратную ссылку на объект в таблице объектов, которая удерживает его (или, по крайней мере, используется).

Когда заполняется куча или таблица объектов, система будет устанавливать флаг "удалить меня" для каждого объекта в таблице. Он будет изучать каждый объект, о котором он знает, и, если его флаг "удалить" был установлен, отключите его и добавьте все объекты, которые он знает, в список объектов, которые будут проверяться. Как только это будет сделано, любой объект, флаг "delete me" все еще установлен, может быть удален.

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