Подтвердить что ты не робот

Поля класса, хранятся ли они в стеке или куче?

Вчера я увидел вопрос, который поднял (для меня) еще один вопрос. Посмотрите на следующий код:

public class Class1
{
   int A; //as I uderstand, int is value type and therefore lives in the stack
}

class Class2
{
    Run()
   {
       Class1 instance1 = new Class1();
       instance1.A = 10;  //it points to value type, but isnt this reference (on heap)?
   }
}

Или при создании экземпляра класса 1 его типы полей также создаются в куче? Но тогда я не понимаю, когда это действительно будет в стеке, поскольку почти всегда вам нужно создать экземпляр объекта, чтобы использовать его.

4b9b3361

Ответ 1

как я понимаю, int - тип значения и, следовательно, живет в стеке

Ваше понимание неверно. Типы значений называются "типами значений", потому что они копируются по значению. Типы ссылок называются "ссылочными типами", потому что они копируются по ссылке. Не совсем верно, что "типы значений всегда живут в стеке". Если бы это было так, они назывались бы типами стека и типами кучи.

По правде говоря, это детализация реализации. Различные реализационные схемы могут использовать стек и кучу по своему усмотрению. Вот как это делает реализация Microsoft:

  • значение переменной ссылочного типа является ссылкой на память кучи. Ссылка в основном представляет собой 32-битное или 64-битное целое число.
  • значением переменной типа значения является ее значение.
  • значения локальных переменных хранятся в стеке, если локальные переменные не находятся в блоке итератора или не являются закрытыми внешними переменными анонимного метода или лямбда-выражения. В этих случаях значения локальных переменных сохраняются в куче. Если, конечно, локальные переменные не могут быть оптимизированы, в этом случае нет никакого хранилища. Или, возможно, они могут быть зарегистрированы, и в этом случае они не находятся ни в стеке, ни в куче, они находятся в регистрах процессоров.
  • значения переменных экземпляра ссылочных типов и статических переменных хранятся в куче.

Это ясно?

указывает на тип значения, но не является ли эта ссылка (в куче)?

Поле "A" имеет тип значения. Это поле, и поэтому эта переменная хранится в куче.

при создании экземпляра Class1, его типы полей также создаются в куче?

Хранилище для переменных экземпляра находится в куче, да.

Но тогда я не понимаю, когда это действительно будет в стеке, поскольку почти всегда вам нужно создать экземпляр объекта, чтобы использовать его.

Это никогда не будет в стеке. Как я сказал выше, единственными вещами, которые идут в стеке, являются локальные переменные (и временные файлы, созданные компилятором), которые не являются закрытыми локалями лямбда-метода или анонимным методом и не находятся в блоке итератора. И, конечно же, дрожание позволяет полностью отключить их от стека и помещать их в регистры, если есть свободные регистры.

Но на самом деле, я должен спросить, почему вам все равно, что происходит в стеке и что происходит в куче? То, что происходит в стеке, - это то, что мы можем дешево положить в стек; все остальное идет в кучу.

Ответ 2

Локальная структура (тип значения) переменные хранятся в стеке, поля типа значения класса хранятся в куче.

Ответ 3

Ok int - это тип значения, но "1" (какое ужасное имя для класса) является ссылочным типом. Это означает, что любой экземпляр "1" находится в куче.