Как будет выглядеть память для этого объекта? - PullRequest
0 голосов
/ 14 октября 2019

Мне интересно, как будет выглядеть структура памяти для этого класса (его объекта):

class MyClass
{
    string myString;

    int myInt;

    public MyClass(string str, int i)
    {
        myString = str;
        myInt = i;
    }
}

MyClass obj = new MyClass("hello", 42);

Может ли кто-нибудь это представить?

Обновление:

Основываясь на ответе Оливье Рожье и комментариях ckuri и Jon Skeet, я попытался создать диаграмму высокого уровня, находящуюся под сильным влиянием статьи devblog , упомянутой ckuri.

Итак, насколько я понимаю:

  1. obj (ссылка на 8 байт) указывает на объект, включая метаданные (на самом деле не на его начало, но давайте для простоты проигнорируем это).

  2. В этом месте хранится myInt и справочное значение myString (которое является ссылкой на действительное строковое значение)

enter image description here

Я не хочу вдаваться в последние детали, но мне все еще интересно:

  1. Если obj.myString должны быть доступны, есть ли два «поиска», например, сначала поиск obj, затем следование и поискup myString или есть что-то вроде глобальной таблицы адресов, в которой адрес для obj.myString непосредственно сохраняется?

  2. Где хранится эталонное значение obj? Является ли он частью объектного блока program, как myString является частью объектного блока obj? (при условии, что obj создается внутри экземпляра program)

Ответы [ 2 ]

3 голосов
/ 15 октября 2019

В этом месте хранится myInt и ссылочное значение myString (которое является ссылкой на действительное строковое значение)

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

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

Во-вторых, неясно, что вы подразумеваете под "реальным значением строки". Строки имеют ссылочный тип. Реальным значением строки является ссылка . Значения содержимого строки находятся в указанном местоположении.

если необходимо получить доступ к obj.myString, нужны ли два «поиска», например, сначала поиск по obj, затем следуя за ним и ища myString

Я предполагаю, что под "поиском" вы подразумеваете разыменование .

Так, например, если у нас есть:

var obj = whatever;
char c = obj.myString[1];

тогда да, у нас есть две разыменования. . разыменовывает obj, чтобы получить myString, который является ссылкой. [1] разыменовывает myString для получения char.

Где хранится эталонное значение obj?

obj является переменной. Переменная является местом хранения. Это место хранения может находиться в нескольких местах:

  • Если obj является кратковременным или, что еще лучше, эфемерным, его можно зарегистрировать или включить в краткосрочный пул. (Более известный как стек, но, на мой взгляд, лучше думать о краткосрочном пуле с точки зрения его семантики, а именно: хранилище, которое живет не дольше, чем активация . Стек являетсяподробности реализации.)

  • Если obj не известен как недолговечный, он переходит в долгосрочный пул, также известный как управляемая куча.

1 голос
/ 14 октября 2019

Во-первых, вам нужно 4 байта на x32 или 8 байтов на x64, чтобы сохранить ссылку на адрес памяти объекта (ссылка - это скрытый указатель, которым забыть управлять им).

Далее объектздесь есть два элемента данных:

  • Одно целое число, которое занимает 4 байта.
  • Одна строка, которая здесь занимает 5 символов: 5x2 байта = 10 байтов.

Таким образом, для данных объект занимает 18 байтов в x32 или 22 байта в системе x64.

Поскольку строковый объект содержит целое число для длины, размер немного больше этого: 22 в x32 и 26 в x64.

Поскольку строка является ссылкой, нам нужно снова добавить 4 или 8 байтов => 26 или 34 байта.

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

C # - действительно ли строка является массивом символов или у нее просто есть индексатор?

В дополнение к этомупамять в сегменте кода имеет инструкцииЭлектронный код методов. Этот код является общим для всех экземпляров.

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

Если объект создается в методеон использует кучу памяти.

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

А память - как поезд, в котором байты - это байты.

Вот псевдограмма памяти.

Это не совсем истинная реальность, но она может помочь понять:

enter image description here

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

Куча C # (ing) против стека (ing) в .NET

Байт - это элементарная единица памяти, которая хранит одно значение за раз от 0 до 255 (без знака) или от -128 до +127 (подписано).

Изучите основы данных C #переменные типов

Поведение смещения для знаковых целых чисел

Руководство по представлению данных

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