Приведи пример объектов, которые размещаются в Large Object Heap (LOH) в .NET

«Приведи пример объектов, которые размещаются в Large Object Heap (LOH) в .NET» — вопрос из категории Управление памятью, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Large Object Heap (LOH) — это специальная область управляемой кучи для объектов, размер которых равен или превышает 85 000 байт. Такие объекты не перемещаются сборщиком мусора (GC).

Примеры объектов LOH:

// 1. Большие массивы примитивных типов (порог ~85 000 байт)
byte[] largeBuffer = new byte[100_000]; // ~100 KB -> LOH
int[] largeIntArray = new int[25000]; // 25k * 4 bytes = 100,000 bytes -> LOH

// 2. Большие строки (каждый символ = 2 байта в .NET)
string hugeString = new string('A', 50_000); // 50k * 2 = 100,000 bytes -> LOH

// 3. Большие массивы ссылочных типов (размер массива = 8 байт на элемент + накладные расходы)
object[] largeObjectArray = new object[20_000]; // Может попасть в LOH

// 4. Коллекции с большой начальной емкостью (capacity)
List<int> bigList = new List<int>(capacity: 50_000); // Внутренний массив будет в LOH
Dictionary<int, string> bigDict = new Dictionary<int, string>(capacity: 10_000);

Практические последствия и best practices:

  • Фрагментация: Поскольку LOH не компактифицируется, частые аллокации/освобождения больших объектов могут привести к фрагментации памяти и OutOfMemoryException, даже если свободной памяти в сумме достаточно.
  • Сборка мусора: LOH собирается только во время сборки мусора поколения 2 (Gen 2), что происходит реже.
  • Рекомендации:
    1. Избегайте создания кратковременных больших объектов (используйте пулы, например ArrayPool<T>).
    2. Переиспользуйте большие массивы, если это возможно.
    3. Рассмотрите альтернативы (например, потоковая обработка данных вместо загрузки всего файла в память).