Что такое куча и стек? Различия, принцип работы.csharp-78

В .NET управление памятью осуществляется через два основных сегмента: стек (stack) и кучу (heap). Они принципиально отличаются по структуре, скорости работы и способам управления памятью.

1. Стек

Характеристики:

  • Быстрый доступ: выделение и освобождение памяти происходит за O(1).
  • LIFO (Last In, First Out): данные кладутся и забираются только с вершины стека.
  • Ограниченный размер: обычно 1-8 МБ (зависит от ОС и настроек).
  • Автоматическое управление: память освобождается при выходе из метода.

Что хранится в стеке?

  • Локальные переменные методов (value types, если они не в ссылочных типах).
  • Аргументы методов.
  • Информация о вызовах методов (call stack).
void Calculate() {
    int a = 5; // Хранится в стеке
    double b = 3.14; // Тоже в стеке
}

2. Куча

Характеристики:

  • Динамическое выделение: размер ограничен только объемом доступной памяти.
  • Медленнее стека: требуется поиск свободного блока памяти.
  • Управляется GC: сборщик мусора освобождает неиспользуемые объекты.
  • Фрагментация: возможна из-за динамического выделения/освобождения.

Что хранится в куче?

  • Объекты ссылочных типов (class, string, массивы).
  • Value types, упакованные в object (boxing).
class Person {
    public int Age; // Хранится в куче (в составе объекта)
}

void CreatePerson() {
    Person p = new Person(); // Сам объект - в куче, ссылка `p` - в стеке
}

Ключевые различия

ХарактеристикаСтекКуча
СкоростьОчень быстрыйМедленнее
Управление памятьюАвтоматическое (LIFO)Управляется GC
РазмерОграниченДинамический
Типы данныхValue types, ссылкиОбъекты ссылочных типов
ПотокобезопасностьТолько для одного потокаДоступна для всех потоков

Пример с упаковкой

int x = 42; // В стеке
object obj = x; // Упаковка: значение копируется в кучу

Оптимизации .NET

  • Стек потока (Thread Stack): у каждого потока свой стек.
  • Малые объекты в куче размещаются в SOH (Small Object Heap), большие — в LOH (Large Object Heap).
  • Gen 0, Gen 1, Gen 2: поколения в куче для оптимизации работы GC.

Когда что использовать?

  • Стек: для временных данных, небольших структур, где важна скорость.
  • Куча: для сложных объектов, которые должны жить дольше метода.

Резюмируем:

стек и куча — это фундаментальные механизмы управления памятью в .NET. Стек быстр, но ограничен, куча гибкая, но требует работы GC. Понимание их различий критично для написания эффективного и безопасного кода.