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

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

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)?
   }
}

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

23
задан Sasha Chedygov 2 April 2010 в 06:38
поделиться

3 ответа

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

2
ответ дан 29 November 2019 в 01:25
поделиться

Насколько я понимаю, int является типом значения и поэтому находится в стеке

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

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

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

Это ясно?

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

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

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

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

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

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

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

44
ответ дан 29 November 2019 в 01:25
поделиться

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

8
ответ дан 29 November 2019 в 01:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: