Сборка мусора не только избавляется от объектов, на которые нет ссылок, но и сжимает кучу. Это очень важная оптимизация. Это не только делает использование памяти более эффективным (без неиспользуемых дыр), но и делает кэш ЦП намного более эффективным. Кэш - это действительно большое дело для современных процессоров, они на порядок быстрее, чем шина памяти.
Сжатие выполняется простым копированием байтов. Однако это требует времени. Чем больше объект, тем больше вероятность того, что затраты на его копирование перевешивают возможные улучшения использования кэша ЦП.
Поэтому они провели несколько тестов, чтобы определить точку безубыточности. И мы достигли 85 000 байт в качестве точки отсечения, когда копирование больше не улучшает производительность. За специальным исключением для массивов типа double, они считаются «большими», если в массиве более 1000 элементов. Это еще одна оптимизация для 32-битного кода, распределитель кучи больших объектов имеет специальное свойство: он выделяет память по адресам, выровненным по 8, в отличие от обычного распределителя поколений, который выделяет только выровненные по 4. Это выравнивание имеет большое значение для double , чтение или запись неверно выровненного двойника очень дорого. Как ни странно, в скудной информации Microsoft никогда не упоминаются массивы длинных, непонятно, что с этим делать.
Fwiw, многие программисты обеспокоены тем, что куча больших объектов не сжимается. Это всегда срабатывает, когда они пишут программы, которые занимают более половины всего доступного адресного пространства. Затем с помощью такого инструмента, как профилировщик памяти, выяснилось, почему программа провалилась, хотя все еще оставалось много неиспользуемой виртуальной памяти. Такой инструмент показывает дыры в LOH, неиспользуемые участки памяти, где раньше находился большой объект, но собирался сборщик мусора. Такова неизбежная цена LOH, дыра может быть повторно использована только путем выделения для объекта, равного или меньшего по размеру. Настоящая проблема заключается в предположении, что программе должно быть разрешено использовать всю виртуальную память в любое время.
Проблема, которая в противном случае полностью исчезнет, просто запустив код в 64-битной операционной системе. 64-битный процесс имеет 8 терабайт адресного пространства виртуальной памяти, что на 3 порядка больше, чем 32-битный процесс. Вы просто не можете выбежать из дыр.
Короче говоря, LOH делает код более эффективным. За счет использования доступного адресного пространства виртуальной памяти менее эффективно.
ОБНОВЛЕНИЕ. .NET 4.5.1 теперь поддерживает сжатие свойства LOH, GCSettings.LargeObjectHeapCompactionMode . Остерегайтесь последствий, пожалуйста.