Короткий ответ: нет, вам не нужно вызывать его дважды.
Теперь давайте копнем немного глубже. GC использует подход, основанный на генерации. То есть куча разбивается на куски, которые используются для оптимизации GC, поэтому он фактически работает в меньших областях памяти. Подробнее о том, как работает GC, можно узнать здесь.
Когда GC запускается, он восстанавливает все объекты из текущего поколения, на которые нет сильных* ссылок (* - можно использовать тип System.WeakReference
, чтобы иметь ссылку на объект, позволяя GC восстанавливать его). Те объекты, которые пережили сборку мусора, переходят в следующее поколение. Если следующее поколение будет достаточно заполнено, сборщик мусора запустится и на нем, перемещая уцелевшие объекты дальше. Сказав это, вы можете видеть, что запуск GC во второй раз, скорее всего, не будет иметь никакого значения.
Однако в сценариях с большой нагрузкой, когда объекты создаются очень быстро, периода времени между двумя последовательными вызовами может быть достаточно (зависит от состояния потока, приоритета — какие вызовы выполняются) для создания достаточно объектов, которые могут добавить вес памяти. В этой ситуации последующий вызов может иметь эффект и очистить хороший кусок памяти. Хотя этот сценарий потенциально возможен, на самом деле это происходит не очень часто. Причина в том, что если есть такая нагрузка, она, вероятно, будет продолжаться, поэтому вызов GC дважды не будет иметь большой разницы...
person
Artak
schedule
02.03.2018
GC.Collect()
собирает все поколения. Я имел в виду сборку мусора в более широком смысле, которая может быть ограничена определенными поколениями. Технически объект пережил сборку, будучи помещенным в очередь на завершение. Теперь это поколение 1 или поколение 2. Коллекция поколения 0 не увидит, что она восстановлена, даже если был запущен финализатор. Таким образом, 2 коллекции любого поколения — это минимум. - person Mike Zboray   schedule 23.06.2016