GC.Collect только на поколении 2 и "куче" для больших объектов

. htaccess:

RewriteEngine on
RewriteCond %{HTTP_REFERER} slashdot\.org [NC]
RewriteRule .* - [F]
8
задан DevinB 23 September 2009 в 22:31
поделиться

2 ответа

Это невозможно. Сборщик мусора спроектирован таким образом, что коллекция поколения 2 всегда также собирает поколения 0 и 1.

Изменить : Вы нашли источник для этого в блоге разработчика сборщика мусора :

Сборщик мусора Gen2 требует полная коллекция (Gen0, Gen1, Gen2 и LOH! Large объекты GC'ed в каждом Gen2 GC даже если сборщик мусора не запускался нехватка места в LOH. Обратите внимание, что там не сборщик мусора, который собирает только большие объекты.), что занимает гораздо больше времени, чем Коллекции младшего поколения.

Редактировать 2 : Из того же блога Использование GC Efficiently Часть 1 и Часть 2 очевидно, коллекции Gen0 и Gen1 быстрее по сравнению с коллекцией Gen2, так что мне кажется разумным, что выполнение только Gen2 не принесет большого выигрыша в производительности. Может быть и более фундаментальная причина, но я не уверен. Может быть, ответ в какой-то статье в этом блоге.

14
ответ дан 5 December 2019 в 08:24
поделиться

Поскольку все новые выделения (кроме больших объектов) всегда поступают в Gen0, сборщик мусора спроектирован так, чтобы всегда собирать данные из указанного поколения и ниже. Когда вы вызываете GC.Collect (2) , вы сообщаете GC собирать данные от Gen0, Gen1 и Gen2.

Если вы уверены, что имеете дело с большим количеством больших объектов (объектов, которые во время выделения достаточно велики, чтобы их можно было разместить в LOH), лучший вариант - убедиться, что вы установили для них значение null (ничего в VB), когда вы закончите с ними. Распределение LOH пытается быть умным и повторно использовать блоки. Например, если вы разместили объект размером 1 МБ в LOH, а затем удалили его и установили значение null, у вас останется «дыра» размером 1 МБ. В следующий раз, когда вы выделите на LOH что-либо размером 1 МБ или меньше , он заполнит эту дыру (и будет заполнять ее до тех пор, пока следующее выделение не станет слишком большим, чтобы поместиться в оставшееся пространство, после чего он выделит новый блок.)

Имейте в виду, что поколения в .NET не являются физические вещи, но являются логическими разделениями, помогающими повысить производительность сборщика мусора. Поскольку все новые выделения идут в Gen0, это всегда первое поколение, которое нужно собрать. В каждом запущенном цикле сбора все в более низком поколении, оставшееся после сбора, «продвигается» к следующему высшему поколению (пока оно не достигнет Gen2).

В большинстве случаев сборщику мусора не нужно выходить за рамки сбора Gen0. Текущая реализация GC может собирать Gen0 и Gen1 одновременно, но не может собирать Gen2, пока собираются Gen0 или Gen1. (.NET 4.0 значительно ослабляет это ограничение и по большей части

6
ответ дан 5 December 2019 в 08:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: