Вы правильно выводите ряд деталей реализации.
Прежде чем вдаваться в эти детали, некоторые термины. Существует три вида хранения:
- неуправляемое хранилище
- управляемое хранилище
- временное хранилище
Неуправляемое хранилище выходит за рамки вашего вопроса. Управляемое хранилище - это то, что мы будем называть «кучей». Временное хранилище - это «стек» или регистры, если дрожание умное и регистры доступны, но в качестве упрощающего допущения позволяет игнорировать регистры и просто вызывать пул временного хранилища «стеком».
Существует четыре вида типов:
- неуправляемые указатели
- типы значений
- ссылки, ака, управляемые указатели
- фактические экземпляры ссылочных типов
Неуправляемые указатели выходят за рамки вашего вопроса. C # позволяет вам манипулировать ссылками («управляемыми указателями») и типами значений напрямую; содержимым экземпляров ссылочного типа манипулируют только через ссылки, и они всегда находятся в куче в реализации CLR. (Ничто не мешает джиттеру создавать экземпляр ссылочного типа в стеке, если у него достаточно смартов, чтобы знать, что объект никогда не нуждается в сборке мусора и не выдерживает метод, но на практике наши дрожания не делают этого, насколько мне известно.)
Другие три вида вещей могут быть в стеке или куче, если необходимо, в зависимости от их времени жизни.
В моем основном методе экземпляр Dog создается и присваивается переменной с именем dog. Я знаю, что происходит в куче, предполагая, что он находится с адреса 0x00FFFF.
Вы предполагаете (правильно), что управляемые ссылки реализованы как адреса в плоском 32-битном адресном пространстве. (На самом деле это не был бы допустимый адрес кучи, но мы позволим ему скользить.) Конечно, реализация CLR не должна использовать необработанные адреса в качестве ссылок. Например, они могут быть непрозрачными ручками в столе, контролируемом ГХ.
В настоящее время я знаю только в стеке, что пространство для собаки имеет значение 0x00FFFFF, но я на 100% уверен, что где-то еще в пространстве для собаки есть свой тип объявления.
Под его "объявленным" типом я думаю, что вы имеете в виду фактический тип времени исполнения экземпляра, Dog. Это сбивающее с толку использование «объявления». Экземпляры не "объявлены"; экземпляры "распределены". Переменные"объявлены", а переменная имеет объявленный тип "Animal".
Да, где-то в фактических данных экземпляра, выделенных для "new Dog ()", есть "токен", который описывает тип времени выполнения объекта. Если вам важны точные сведения о том, как работает токен, задайте другой вопрос.
Я хочу знать подробное объяснение стекового пространства для собаки, в настоящее время я знаю, что там есть ссылочный адрес, что-нибудь еще?
Ваш вопрос неоднозначен, поскольку в стеке есть две переменные, и ни одна из них не названа "собака".
Во время выполнения пространство стека просто содержит управляемую ссылку на пространство кучи, выделенное для экземпляра. Компилятор C # знает, что стековое пространство для dog1 имело тип управляемой ссылки на Animal во время компиляции, а стековое пространство для dog2 имело тип управляемой ссылки на Dog во время компиляции. Поэтому джиттер также знает эту информацию. Джиттер хранит информацию об этом в своих собственных структурах данных; это не загрязняет стек. Джиттер может хранить эту информацию для оптимизации или для целей отладки. Или он может выбросить его, если ему больше не нужна эта информация.
Это опять-таки деталь реализации; джиттер совершенно свободен, чтобы поместить любую дополнительную информацию в стек, который ему нравится.