В чем разница для сборщика мусора между объектом размером 10 КБ и 100 КБ?

«В чем разница для сборщика мусора между объектом размером 10 КБ и 100 КБ?» — вопрос из категории Управление памятью, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Основное различие заключается в том, как объекты размещаются в памяти и как это влияет на производительность сборки мусора (GC).

  • Размещение в куче: В .NET (и многих других управляемых средах) объекты свыше 85 000 байт (~85 КБ) считаются большими объектами (LOH — Large Object Heap). Таким образом, объект в 100 КБ попадет в LOH, а объект в 10 КБ — в кучу малых объектов (SOH).
  • Сборка мусора:
    • SOH: Сборка мусора для малых объектов происходит часто и использует алгоритм сжатия (перемещение живых объектов для устранения фрагментации). Это эффективно, но требует процессорного времени.
    • LOH: Сборка мусора для больших объектов происходит реже, но сборщик мусора не сжимает LOH по умолчанию (из-за высоких затрат на копирование больших блоков памяти). Это может привести к фрагментации LOH.
  • Практическое влияние:
    1. Фрагментация: Частое создание и удаление больших объектов (100 КБ+) может вызвать фрагментацию LOH, что приведет к OutOfMemoryException, даже если свободной памяти в сумме достаточно.
    2. Производительность: Аллокация и освобождение одного объекта в 100 КБ сопоставима по накладным расходам с аллокацией десяти объектов по 10 КБ, но последствия фрагментации для LOH более серьезны.

Рекомендация: По возможности избегайте создания кратковременно живущих больших объектов (например, большие буферы в циклах). Используйте пулы объектов или переиспользуйте массивы.