CLR - где хранятся ссылочные адреса? - PullRequest
4 голосов
/ 30 октября 2011

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

Предположим, у нас есть следующее утверждение:

Int32 i = 1;

i содержимое хранится в памяти, которая будет четыре байта: 00000000 00000000 00000000 00000001

Как CLR получает доступ к этой ячейке памяти позже? Хранит ли CLR адрес этого блока памяти где-нибудь?

Ответы [ 4 ]

4 голосов
/ 30 октября 2011

System.Int32 является типом значения, ссылки не используются.

Фактически, локальная переменная может вообще никогда не быть в памяти, если компилятор может найти регистр ЦП для хранения его в течение всей своей жизни.

Если он находится в памяти, его адрес будет найден путем добавления смещения к указателю стека (ESP) или к адресу объекта со ссылочным типом (class в C #), который его содержит.

В коде, сгенерированном из JIT, переменные типов значений неотличимы от переменных, используемых собственным кодом (нет заголовка объекта или чего-либо подобного).

3 голосов
/ 30 октября 2011

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

В этом случае вы объявляете локальную переменную, поэтому она будет размещена наthe stack.

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

Код дляустановка переменной в 1 может, например, выглядеть так, когда она скомпилирована в машинный код для 32-битного приложения:

mov dword ptr [ebp-8],1

Регистр ebp указывает на верхнюю часть фрейма стека, поэтому i переменной в данном случае выделяется на восемь байтов меньше, чем

2 голосов
/ 30 октября 2011

Допустим, что НОРМАЛЬНО, если i является локальной переменной, она будет сохранена в стеке. abstract VM .NET является основанной на стеке.

Я добавлю, что на Intel / AMD i не будет сохранен таким образом :-) Intel / AMD little endian .Так что это будет 00000001 00000000 00000000 00000000

Я немного смешаю ... Теперь ... Язык IL и .NET abstract VM основаны на "чистом" стеке, поэтомуесть стек :-) (но регистров нет, поэтому «чистый») (надеюсь, вы знаете, что такое стек).Когда код вписывается в машинный код компьютера, который вы используете, вероятно, i будет помещен в регистр или в стек.

Обратите внимание, что в общем это неправильно неправильно неправильносказать, что типы значений (или не ссылочные типы, если вы хотите включить управляемые / неуправляемые указатели / ссылки) сохраняются в стеке и / или в регистрах.Они сохраняются там, где они сохранены.Например, типы значений-членов класса сохраняются с (в) классом (поэтому обычно в куче).Типы значений в функциях yield, в асинхронных функциях, в «нормальных» методах, но на которые ссылаются анонимные функции «типа закрытия», обычно сохраняются где-то в куче.Но все это подробности справочных реализаций.

0 голосов
/ 30 октября 2011

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

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