Да, это становится важным, когда ваш List<T>
становится большим. Точные числа зависят от типа элемента и архитектуры машины, давайте выберем Список ссылочных типов на 32-битной машине. Затем каждый элемент займет 4 байта во внутреннем массиве. Список начнется с емкости 0 и пустого массива. Первый Add()
вызов увеличивает емкость до 4, перераспределяя внутренний массив до 16 байтов. Спустя четыре Add()
вызова массив заполнен, и его необходимо снова перераспределить. Он увеличивает размер вдвое, емкость увеличивается до 8, размер массива до 32 байтов. Предыдущий массив - мусор.
Это повторяется по мере необходимости, несколько копий внутреннего массива станут мусором.
Что-то особенное происходит, когда массив увеличивается до 65 536 байт (16 384 элемента). Следующая функция Add () снова удваивает размер до 131 072 байта. Это выделение памяти, превышающее пороговое значение для «больших объектов» (85 000 байт). Распределение теперь больше не выполняется в куче поколения 0, оно берется из кучи больших объектов.
Особо обрабатываются объекты на LOH. Они только собираются мусором во время сборки поколения 2. И куча не уплотняется, перемещение таких больших кусков занимает слишком много времени.
Это повторяется по мере необходимости, несколько объектов LOH станут мусором. Они могут занимать память довольно долго, коллекции поколения 2 бывают нечасто. Другая проблема заключается в том, что эти большие блоки имеют тенденцию фрагментировать адресное пространство виртуальной памяти.
Это не повторяется бесконечно, рано или поздно классу List необходимо перераспределить массив, и он стал настолько большим, что в адресном пространстве виртуальной памяти не осталось дыры для размещения массива. Ваша программа будет бомбить OutOfMemoryException. Обычно задолго до того, как вся доступная виртуальная память будет израсходована.
Короче говоря, установив емкость заранее, до того, как вы начнете заполнять список, вы можете заранее зарезервировать этот большой внутренний массив. Вы не получите все эти неудобно выпущенные блоки в куче больших объектов и избежите фрагментации. Фактически, вы сможете хранить гораздо больше объектов в списке, и ваша программа будет работать более компактно, поскольку там так мало мусора. Делайте это только в том случае, если вы хорошо представляете, насколько большим будет список, использование большой емкости, которую вы никогда не заполните, будет расточительным.
person
Hans Passant
schedule
11.02.2010