Ответ 1
как я понимаю, int - тип значения и, следовательно, живет в стеке
Ваше понимание неверно. Типы значений называются "типами значений", потому что они копируются по значению. Типы ссылок называются "ссылочными типами", потому что они копируются по ссылке. Не совсем верно, что "типы значений всегда живут в стеке". Если бы это было так, они назывались бы типами стека и типами кучи.
По правде говоря, это детализация реализации. Различные реализационные схемы могут использовать стек и кучу по своему усмотрению. Вот как это делает реализация Microsoft:
- значение переменной ссылочного типа является ссылкой на память кучи. Ссылка в основном представляет собой 32-битное или 64-битное целое число.
- значением переменной типа значения является ее значение.
- значения локальных переменных хранятся в стеке, если локальные переменные не находятся в блоке итератора или не являются закрытыми внешними переменными анонимного метода или лямбда-выражения. В этих случаях значения локальных переменных сохраняются в куче. Если, конечно, локальные переменные не могут быть оптимизированы, в этом случае нет никакого хранилища. Или, возможно, они могут быть зарегистрированы, и в этом случае они не находятся ни в стеке, ни в куче, они находятся в регистрах процессоров.
- значения переменных экземпляра ссылочных типов и статических переменных хранятся в куче.
Это ясно?
указывает на тип значения, но не является ли эта ссылка (в куче)?
Поле "A" имеет тип значения. Это поле, и поэтому эта переменная хранится в куче.
при создании экземпляра Class1, его типы полей также создаются в куче?
Хранилище для переменных экземпляра находится в куче, да.
Но тогда я не понимаю, когда это действительно будет в стеке, поскольку почти всегда вам нужно создать экземпляр объекта, чтобы использовать его.
Это никогда не будет в стеке. Как я сказал выше, единственными вещами, которые идут в стеке, являются локальные переменные (и временные файлы, созданные компилятором), которые не являются закрытыми локалями лямбда-метода или анонимным методом и не находятся в блоке итератора. И, конечно же, дрожание позволяет полностью отключить их от стека и помещать их в регистры, если есть свободные регистры.
Но на самом деле, я должен спросить, почему вам все равно, что происходит в стеке и что происходит в куче? То, что происходит в стеке, - это то, что мы можем дешево положить в стек; все остальное идет в кучу.