2009-07-15 2 views
4

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

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

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

ответ

1

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

Референтные типы выделяются в куче. Куча в основном представляет собой блок памяти, используемый для этой цели. Объект, хранящийся в куче, является в основном полями объекта, хранящегося в памяти, выделенной для объекта. Таким образом, поля типа значения сохраняются «внутри» объекта в куче. Поля типа ссылки сохраняются в качестве ссылки (или указателя) на указанный объект. Память на куче управляется сборкой мусора. Это сложный вопрос, но рассказ состоит в том, что память, выделенная неиспользуемым объектам в куче, освобождается и, таким образом, появляется возможность повторного использования через сборщик мусора через регулярные промежутки времени.

10

Это гораздо сложнее, чем вы могли бы подумать. Даже ваше утверждение о том, что «типы значений выделены в стеке» неверно. Например:

class Foo 
{ 
    int x; 
} 

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

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

У меня есть article about C# heap/stack memory, который может вам пригодиться, но вы также можете прочитать сообщение в блоге Eric Lippert по адресу "The stack is an implementation detail". В частности, будущий компилятор C# может решить сохранить все свои локальные переменные в куче, используя стек только для хранения ссылки на экземпляр, созданный в начале метода ... который не будет игнорировать спецификацию C# на все.

3

Тип значения «выделяется» там, где он определен.

Что это значит, зависит от того, где вы определяете его:

  • В классе/структуры, как поле в этой структуры, расширение класса/структуры в памяти, чтобы соответствовать значение типа значения там
  • В качестве локальной переменной в методе, в стеке или в виде реестра или в качестве поля в сгенерированном классе (при использовании «замыканий»), в зависимости от оптимизации
  • В качестве параметра к методу в стеке или как регистр, в зависимости от оптимизации

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

Другими словами, сама ссылочная переменная «выделяется» как тип значения, но объект, к которому он относится, находится в куче.

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

Как мне кажется, у Джона Скита есть статья об этом предмете, я уверен, что он скоро придет с ответом, поэтому следите за обновлениями.

+3

И вот он был, пока я печатал свой ответ. –

2

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

Смежные вопросы