Всегда ли экземпляр класса (class) хранится в куче в C#?

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

Ответ

Да, экземпляр класса (объект) в C# всегда размещается в управляемой куче (heap). Это фундаментальное отличие от структур (struct). Однако ссылка на этот объект (переменная) может храниться в разных местах.

Пример:

class MyClass { public int Value; }

void ExampleMethod()
{
    // Переменная 'obj' (ссылка) хранится в стеке.
    // Сам объект new MyClass() размещается в куче.
    MyClass obj = new MyClass();
    obj.Value = 10;
}

Ключевые моменты:

  • Ссылки (например, локальные переменные, параметры, поля) могут находиться в стеке или куче.
  • Объект (данные класса) всегда в куче.
  • Это справедливо даже для struct, которая является полем класса — сама структура хранится в куче внутри объекта-владельца.

Исключения и нюансы:

  1. Стек-аллоцированные ссылки (ref struct): Специальные типы, которые не могут попасть в кучу.
  2. Оптимизации компилятора/рантайма: В определенных сценариях (например, escape analysis в .NET Core/5+) объект может быть размещен на стеке, но это внутренняя оптимизация, не меняющая логическую модель.