Я вчера видел вопрос, который поднял (для меня) другой вопрос. Посмотрите на следующий код:
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, его типы поля создаются на "куче" также? Но затем я не понимаю, когда это действительно было бы на стеке как почти всегда, необходимо создать объект-экземпляр для использования его поля.
Хорошо, int - это тип значения, а «1» (какое ужасное имя для класса) - ссылочный тип. Это означает, что любой экземпляр «1» находится в куче.
Насколько я понимаю, int является типом значения и поэтому находится в стеке
Ваше понимание неверно. Типы значений называются «типами значений», потому что они копируются по значению. Ссылочные типы называются «ссылочными типами», потому что они копируются по ссылке. Вовсе не верно, что «типы значений всегда живут в стеке». Если бы это было правдой, их бы называли «типами стека» и «типами кучи».
На самом деле это деталь реализации. Различные реализации фреймворка могут использовать стек и кучу по своему усмотрению. Вот как это делает реализация Microsoft:
Это ясно?
это указывает на тип значения, но разве это не ссылка (в куче)?
Поле «A» относится к типу значения. Это поле, поэтому эта переменная хранится в куче.
при создании экземпляра Class1 его типы полей также создаются в куче?
Хранилище для переменных экземпляра находится в куче, да.
Но тогда я не понимаю, когда он действительно будет в стеке, поскольку почти всегда вам нужно создать экземпляр объекта, чтобы использовать его поля.
Это никогда не будет в стеке. Как я сказал выше, единственные вещи, которые помещаются в стек, - это локальные переменные (и временные переменные, созданные компилятором), которые не являются закрытыми локальными переменными лямбда или анонимного метода и не находятся в блоке итератора. И, конечно же, джиттер может полностью исключить их из стека и поместить их в регистры, если есть свободные регистры.
Но на самом деле, я должен спросить, почему вас волнует, что находится в стеке, а что - в куче? В стек попадает то, что мы можем без больших затрат положить в стек; все остальное идет в кучу.
Локальные переменные struct (тип значения) хранятся на стеке, поля класса типа значения хранятся на куче.