Что происходит с памятью при создании переменной значимого и ссылочного типа? Почему частые аллокации в куче могут снижать производительность?

C# / .NET Основы языка Junior

Что это: Значимые типы (struct, int, bool) хранятся в стеке (или inline внутри другого объекта), ссылочные типы (class, string, array) — в куче, а ссылка на них — на стеке. При сборке мусора (GC) всё из кучи нужно проверять и освобождать.

Почему важно: Понимание стека и кучи критично для написания предсказуемого кода без утечек и проблем с производительностью — это база, которую проверяют даже на Junior-собеседованиях.

Под капотом: CLR выделяет стек под каждый поток (быстро, по LIFO), а кучу управляет GC. Частые аллокации в куче заставляют GC чаще запускать сборки (Gen0, Gen1, Gen2), что приводит к паузам в работе приложения (stop-the-world).

Типичная ошибка: Новички часто создают много мелких объектов в циклах (например, new MyClass() внутри for), не задумываясь, что это нагружает GC, в то время как можно было использовать структуру или переиспользовать объект.

struct Point { public int X; public int Y; }
class Rectangle { public int Width; public int Height; }

Point p = new Point(); // в стеке или внутри другого объекта
Rectangle r = new Rectangle(); // в куче, ссылка на стеке