2017-02-18 2 views
2

Я пытаюсь понять, как объекты хранятся в памяти с использованием .NET Framework.Как хранятся объекты в памяти?

Учитывая следующий person класс:

public class Person 
{ 
    public string name { get; set; } 

    public int age { get; set; } 
} 

Я считаю, инициированным переменная типа Person будет иметь следующую структуру в памяти: Person Memory Structure

Вопросы:

  • Во-первых, являются ли они основными или очевидными недостатками в моем понимании? (Я почти уверен, что есть, так как это просто кажется эффективным для обработки объектов таким образом, как я описываю, особенно в том, как указатель name указывает на коллекцию символов для элемента строки)

  • Во-вторых, для элементов типа значения класса (IE Age) они хранятся внутри самого объекта (так в том же адресе памяти, что и объект), или им присваивается собственный адрес, а затем объект указывает на него? (Как показано на диаграмме)

  • Как и в предыдущем вопросе, но для ссылочных типов элементов, содержит ли объект указатель на указатель? (I.E Указатель имени, ссылающийся на коллекцию char на моей диаграмме)

  • И, наконец, было бы иметь значение, если бы члены моего класса Person были полями, а не свойствами?

Обновление: обновления схемы на основе ответов от Sweeper & Тима, который я считаю, теперь правильно.

Correct Diagram

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

ответ

1

Начну с самого простого до ответа вопрос:

Будет ли это сделать разницу, если члены моего класса Person были поля, а не свойства?

№ Объекты в вашем коде - это просто синтаксический сахар. Когда код скомпилирован, эти свойства с { get; set; } будут преобразованы в поля с геттером и сеттер.

Есть ли какие-либо серьезные/очевидные недостатки в моем понимании?

Да. Я упомянул их, когда я отвечу на следующие вопросы.

Во-вторых, для членов типа значения класса (IE Age) они хранятся внутри самого объекта (так что в пределах одного и того же адреса памяти, что и объект), или им присваивается собственный адрес, а объект указывает на это?(Как показано на диаграмме)

Ваше первое утверждение верно. Типы значений хранятся внутри объекта. В объекте Person нет указателя, указывающего на int. Другими словами, ваша диаграмма неверна.

но для элементов ссылочного типа, содержит ли объект указатель на указатель? (I.E Указатель имени, ссылающийся на коллекцию char на моей диаграмме)

В этом случае char[] является ссылочным типом, как вы заметили. Но на самом деле он держит кучу char s, которые являются типами значений. Таким образом, нет, символы хранятся в массиве символов, точно так же, как Age хранится в Person. С другой стороны, если это был string[], был бы указатель, указывающий на массив, который будет содержать указатели, указывающие на строковые объекты. Это также означает, что ваша диаграмма неверна.

+0

Благодарим вас за разъяснение. Я добавил обновленную диаграмму, основанную на ваших ответах и ​​ответах Тима, которые, как я считаю, теперь правильны? – KidCode

+0

@KidCode да, это правильно. – Sweeper

2

В мире .net указатели указывают на неуправляемую память, а ссылки на объекты ссылаются на управляемые объекты. Объекты могут быть перемещены сборщиком мусора в любое время, поэтому указатели на них будут уничтожены без предупреждения. Концепция такая же, но есть разница, так как вы действительно можете иметь указатели на небезопасный код C#. Если вы захватите указатель на объект и этот объект перемещается, ваш указатель указывает на произвольное пространство памяти. Однако ссылка на объект сохраняется.

На вопрос о возрасте. Он хранится в самом объекте, занимая 32 бита прямо в структуре - не ссылка/указатель на int32

Для ссылочных типов элементов он содержит ссылку, которая концептуально та же идея, что и указатель и занимает 64 бита пространства (или 32, в зависимости от архитектуры), но несколько отличается, как я уже упоминал выше.

Наконец, анонимные свойства действительно создают скрытые поля и код автоматической записи, который устанавливает и перенастраивает эти поля. Хранение - это то же самое, но есть очень минимальные затраты на доступ к нему через свойство, а не непосредственно в поле.

3

Есть некоторые ошибки. У вас есть член int неправильно, это тип значения. Таким образом, никакой указатель не включен в хранилище для объекта Person и занимает 4 байта. Ссылка ссылка на объект также выглядит не совсем корректно, она указывает на объект String. Шрифты в строке включены в хранилище для строки, так же, как и int. Или, говоря иначе, размер хранилища объектов String является переменным, настолько большим, насколько это необходимо для хранения символов.

Так что посещение членов объекта Person происходит разыменованием только двух указателей, гораздо более эффективным таким образом.

И да, переменная типа Person хранит только указатель. GC обновляет его, когда он уплотняет кучу.

Свойства не существуют во время выполнения, это абстракция, предоставляемая компилятором. Как правило, компилятор будет выделять для него поле, если вы сами не предоставите методы getter и setter. Таким образом, «имя» и «возраст» на вашем чертеже являются фактически полями, у них будет другое имя.