В чем разница между стеком (stack) и кучей (heap) в управлении памятью .NET?

«В чем разница между стеком (stack) и кучей (heap) в управлении памятью .NET?» — вопрос из категории Управление памятью, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Стек (Stack) — это упорядоченная область памяти, работающая по принципу LIFO (Last-In-First-Out). Управляется напрямую процессором и ОС.

  • Что хранится: Локальные переменные значимых типов (int, bool, struct) и ссылки на объекты в куче.
  • Выделение/освобождение: Память выделяется и освобождается автоматически и мгновенно при входе в метод и выходе из него (путем сдвига указателя стека).
  • Размер: Ограничен (обычно ~1 МБ на поток). Переполнение приводит к StackOverflowException.
  • Производительность: Очень высокая, так как выделение — это просто сдвиг указателя.

Куча (Heap) — это неупорядоченная область памяти, используемая для динамического выделения.

  • Что хранится: Объекты ссылочных типов (class, string, array).
  • Выделение/освобождение: Память выделяется при создании объекта (new). Освобождается сборщиком мусора (Garbage Collector, GC) автоматически, когда объект больше не достижим. Это процесс, требующий времени.
  • Размер: Ограничен только доступной виртуальной памятью процесса.
  • Фрагментация: Может возникать, управляется GC.
  • Производительность: Медленнее стека из-за сложности выделения и работы GC.

Практический пример в C#:

void Process()
{
    int localValue = 42; // Значимый тип (int) - хранится в стеке.

    MyClass obj = new MyClass(); // Ссылочный тип (class).
    // 1. В стеке создается переменная 'obj' (ссылка).
    // 2. В куче выделяется память для экземпляра MyClass.
    // 3. Ссылка на этот участок кучи записывается в переменную 'obj'.
}

class MyClass { public int Data; } // Определение ссылочного типа.

Итог: Стек — для быстрых, короткоживущих данных метода. Куча — для объектов, время жизни которых выходит за рамки одного метода.