Ответ
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), что происходит реже.
- Рекомендации:
- Избегайте создания кратковременных больших объектов (используйте пулы, например
ArrayPool<T>). - Переиспользуйте большие массивы, если это возможно.
- Рассмотрите альтернативы (например, потоковая обработка данных вместо загрузки всего файла в память).
- Избегайте создания кратковременных больших объектов (используйте пулы, например