Переменная типа значения выделяет память в стеке, тогда как ссылочный тип выделяет ее в куче.
Нет, это утверждение совершенно неверно. Многие люди верят в это, но это, очевидно, ложно, как вы обнаружили.
Как распределяется память, когда переменная типа значения int i = 4;
объявляется как поле ссылочного типа?
Ясно, что вы знаете, почему ваше первое утверждение совершенно неверно. Целочисленное поле класса не может быть размещено в стеке, поскольку объект может жить дольше, чем кадр стека.
Чтобы понять, что на самом деле происходит, сначала вы должны понять, что существует три вида вещей:
- типы значений
- ссылки
- экземпляры ссылочного типа
Ссылки и экземпляры ссылочного типа совершенно разные, точно так же, как лист бумаги, содержащий мой адрес и мой фактический дом, совершенно разные.
Следующее, что вы должны понять, это то, что существует два вида хранилищ: долговременное и временное хранилище. Долгосрочное хранение обычно называют «кучей», но я предпочитаю думать об этом просто как о долговременном хранении. Временное хранилище обычно называют «стеком», но это также вводит в заблуждение, поскольку, конечно, может быть несколько стеков, могут быть временные файлы, хранящиеся в регистрах, и т. Д.
Экземпляр ссылочного типа занимает память в долговременном хранилище. (Иногда можно определить, что экземпляр ссылочного типа недолговечен, и поместить его во временное хранилище, но мы не проводим эту оптимизацию на практике.)
переменная - это место хранения, в котором хранится либо значение типа значения , либо ссылка .
Место хранения переменной зависит от времени жизни переменной . Если переменная является локальной переменной, о которой известно, что она имеет короткий срок жизни, она выделяется из пула временного хранения. Если известно, что переменная имеет длительный срок службы (потому что, скажем, это внешняя переменная замыкания), то она выделяется из пула долгосрочного хранения.
Если переменная является полем класса, мы уже знаем, что ее хранилище происходит из долгосрочного пула. Если переменная является полем типа значения, этот тип значения где-то находится в хранилище; поле обитает в том же хранилище.
Если переменная является элементом массива, она выделяется из пула долгосрочного хранения; массивы являются экземплярами ссылочного типа.
Ключ к правильному пониманию заключается в том, чтобы просто перестать верить в миф о том, что , является ли переменная справочной или типом значения, влияет на место хранения . Это неправда и никогда не было правдой, и даже не имеет никакого смысла.
Единственное, что влияет на то, где хранится переменная, это как долго переменная живет в . Краткосрочные переменные выделяются из временного пула - стека или регистров - а долговременные переменные выделяются из пула долговременного хранения - кучи.