Что такое куча и стек? Различия, принцип работы.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. Понимание их различий критично для написания эффективного и безопасного кода.