Ответ
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>). - Переиспользуйте большие массивы, если это возможно.
- Рассмотрите альтернативы (например, потоковая обработка данных вместо загрузки всего файла в память).
- Избегайте создания кратковременных больших объектов (используйте пулы, например
Ответ 18+ 🔞
А, Large Object Heap! Ну это, блядь, такая специальная помойка в .NET, куда летят все объекты, которые больше 85 килобайт. Представь себе — обычная куча, там мусорщик постоянно убирается, вещички по полочкам раскладывает. А LOH — это как гараж твоего алкаша-соседа: закинул туда старый двигатель от «Жигулей», и он там навсегда. Не двигается, не компактится, просто лежит и ждёт, пока его не прибьёт сборка мусора второго поколения.
Вот что обычно туда отправляется на вечное поселение:
// 1. Большие массивы примитивов (порог тот самый, 85КБ)
byte[] largeBuffer = new byte[100_000]; // ~100 КБ — однозначно в LOH, пиши пропало
int[] largeIntArray = new int[25000]; // 25 тысяч * 4 байта = сотня килобайт — тоже туда
// 2. Огромные строки (каждый символ — два байта, не забывай)
string hugeString = new string('A', 50_000); // 50к * 2 = 100КБ — прощай, обычная куча
// 3. Массивы ссылочных типов, если их много-премного
object[] largeObjectArray = new object[20_000]; // Может и сюда впендюриться
// 4. Коллекции, которые с самого начала забили себе огромный внутренний массив
List<int> bigList = new List<int>(capacity: 50_000); // Внутренний массив — сразу в LOH
Dictionary<int, string> bigDict = new Dictionary<int, string>(capacity: 10_000); // И эта тоже
А теперь, сука, практические грабли, на которые все наступают:
-
Фрагментация: Это главная беда. Поскольку там ничего не уплотняют, можно получить классическую ситуацию: свободной памяти вроде дохуя, а непрерывного куска в 100КБ — нихуя. И вылетает
OutOfMemoryException, хотя по факту место есть. Просто всё в дырках, как сыр швейцарский, блядь. -
Сборка мусора: LOH убирают только вместе с полной, генерационной уборкой (Gen 2), которая случается нечасто. Так что твой хлам может лежать там долго и счастливо.
-
Что делать, чтобы не выстрелить себе в ногу:
- Не создавай, блядь, одноразовые большие объекты. Сделал буфер на 100 мегабайт, обработал и выбросил? Да ты конченый оптимист! Используй пулы, тот же
ArrayPool<T>— взял, использовал, вернул. - Переиспользуй, что можно. Если уж выделил здоровенный массив, не отпускай его на волю, держи при себе и используй снова.
- Может, не надо всё в память-то пихать? Файл на 2 гигабайта читаешь? Может, потоково его обрабатывать, а не целиком в память загонять? Подумай головой иногда, ебать!
- Не создавай, блядь, одноразовые большие объекты. Сделал буфер на 100 мегабайт, обработал и выбросил? Да ты конченый оптимист! Используй пулы, тот же
Короче, LOH — не враг, но и друг он тебе не товарищ. Относись к нему с уважением, и будет тебе счастье, а не исключения памяти.