Я сделаю все мои разговоры w.r.t. Язык C #:
Цитирую вас :
как мы знаем, ссылочные типы всегда хранятся в куче и типах значений.
находятся в памяти стека.
TL; DR; Это не так. Пожалуйста, прочитайте подробности, которые я разместил ниже. В вашем случае экземпляр объекта класса A
и переменная-член myInt
будут храниться в куче независимо от того, что myInt
является типом значения.
Подводя итог, как переменные хранятся в куче и стеке: :
Стек всегда используется для хранения следующих двух вещей:
- Ссылочная часть ссылочных локальных переменных в функциях и их параметры.
- Типизированные локальные переменные и параметры метода (структуры, а также целые числа, значения типа bool, char, DateTimes и т. Д.)
В куче хранятся следующие данные:
- Содержимое объектов ссылочного типа.
- Все, что структурировано внутри объекта ссылочного типа.
1038 * Е.Г. *
Main()
{
MyClass obj = new MyClass();
}
Class MyClass
{
int32 i;
Dataset dst;
private void MyMethod(int32 j, dataset dst2)
{
int32 k;
Dataset dst3;
}
Вот детали выделения памяти:
- obj, являющийся ссылкой на объект - стек
- Экземпляр Myclass, на который указывает переменная obj - Управляемая куча
- Тип значения Переменная-член i - управляемая куча
- dst - ссылка на объект набора данных - управляемая куча
- Экземпляр набора данных, на который указывает переменная dst - Управляемая куча
- Параметр типа значения j - стек
- dst2, который является ссылкой на объект набора данных - стек
- Экземпляр набора данных, на который указывает переменная dst2 - Управляемая куча
- Тип значения Локальная переменная k - стек
- dst3, который является ссылкой на объект набора данных - стек
- Экземпляр набора данных, на который указывает dst3 - Управляемая куча
Я думаю, что покрыл все перестановки и комбинации.
Снова цитирую :
теперь, как объект класса (куча) взаимодействует с публичной переменной myInt
(Стек)
Первое, что я хочу добавить, это то, что объект и переменные не взаимодействуют. Это код (исполняемые инструкции IL, присутствующие в методе), которые взаимодействуют с открытыми переменными экземпляра класса (он же объект).
Смотрите, CLR загружает тип только один раз в память. Таким образом, все инструкции IL, соответствующие вашему методу Display
, будут находиться в центре памяти независимо от количества экземпляров класса A
, которые вы создаете в своей программе. Только экземпляры (содержащие данные переменных-членов) класса A
будут занимать другое место (точнее, адрес памяти) в куче.
Поэтому, когда выполняется инструкция IL для метода Display
, он имеет указатель на this
, который является ссылкой на текущий экземпляр объекта в куче. this
ссылка различна для разных экземпляров объекта. this
всегда указывает на начальный макет адреса памяти вашего текущего экземпляра объекта. Оттуда требуется смещение, чтобы добраться до адреса памяти, где находится myInt
, чтобы получить доступ / изменить его.
Надеюсь, это поможет вам создать мысленную модель того, как код C # работает под капотом в среде CLR.