Выделение памяти для переменной, объявленной в классе - PullRequest
10 голосов
/ 08 сентября 2011

Как переменная типа Значение выделяет память в стеке, а как тип ссылки выделяет ее в куче.

Так как память выделяется, когда переменная типа значения (например, int i = 4;) объявляется в ссылочном типе (например, в классе).

Как общее распределение памяти работает в .net для типа значения и ссылочного типа, а также типа значения внутри области действия типа ссылки.

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

Спасибо

Ответы [ 4 ]

18 голосов
/ 08 сентября 2011

Переменная типа значения выделяет память в стеке, тогда как ссылочный тип выделяет ее в куче.

Нет, это утверждение совершенно неверно. Многие люди верят в это, но это, очевидно, ложно, как вы обнаружили.

Как распределяется память, когда переменная типа значения int i = 4; объявляется как поле ссылочного типа?

Ясно, что вы знаете, почему ваше первое утверждение совершенно неверно. Целочисленное поле класса не может быть размещено в стеке, поскольку объект может жить дольше, чем кадр стека.

Чтобы понять, что на самом деле происходит, сначала вы должны понять, что существует три вида вещей:

  • типы значений
  • ссылки
  • экземпляры ссылочного типа

Ссылки и экземпляры ссылочного типа совершенно разные, точно так же, как лист бумаги, содержащий мой адрес и мой фактический дом, совершенно разные.

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

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

переменная - это место хранения, в котором хранится либо значение типа значения , либо ссылка .

Место хранения переменной зависит от времени жизни переменной . Если переменная является локальной переменной, о которой известно, что она имеет короткий срок жизни, она выделяется из пула временного хранения. Если известно, что переменная имеет длительный срок службы (потому что, скажем, это внешняя переменная замыкания), то она выделяется из пула долгосрочного хранения.

Если переменная является полем класса, мы уже знаем, что ее хранилище происходит из долгосрочного пула. Если переменная является полем типа значения, этот тип значения где-то находится в хранилище; поле обитает в том же хранилище.

Если переменная является элементом массива, она выделяется из пула долгосрочного хранения; массивы являются экземплярами ссылочного типа.

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

Единственное, что влияет на то, где хранится переменная, это как долго переменная живет в . Краткосрочные переменные выделяются из временного пула - стека или регистров - а долговременные переменные выделяются из пула долговременного хранения - кучи.

6 голосов
/ 08 сентября 2011

Вот почему Эрик Липперт напоминает нам, что стек - это деталь реализации.

Когда экземпляр типа значения является членом ссылочного типа yes, он сохраняется в управляемой куче вместе с родительским объектом. Это хороший вопрос и то, что вы должны понимать, но не то, что должно стимулировать ваш дизайн в большинстве сценариев.

structs должны быть небольшими простыми типами данных, которые относительно дешевы в создании и передаче. Типы ссылок - это ваши сложные типы, для передачи на метод требуется только копия ссылки, но, конечно, они должны быть с некоторым багажом из-за их размещения в куче. Вот хороший ответный пост о последствиях распределения стека и кучи.

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

2 голосов
/ 08 сентября 2011

Так, как память выделяется, когда переменная типа значения (например, int i = 4;) объявляется в ссылочном типе (например, в классе).

Если объект лежит в куче, это означает, что все его переменные-члены находятся там.

1 голос
/ 08 сентября 2011

вот хорошая статья .

Кстати: не всегда значение в стеке идет - оно может заканчиваться в куче.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...