Сборка мусора против общих указателей - PullRequest
12 голосов
/ 12 января 2011

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

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

Ответы [ 3 ]

16 голосов
/ 12 января 2011

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

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

14 голосов
/ 12 января 2011

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

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

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

1 голос
/ 12 января 2011

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

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

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

...