Как объекты (ссылочные типы - куча) взаимодействуют с переменными, хранящимися в стеке - PullRequest
1 голос
/ 09 марта 2010

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

, например

public Class A{
  public int myInt=10;
  public void Display(){
  }
}

здесь, если я создаю объект класса A, он помещается в кучу, а myInt помещается в стек, верно ..?

теперь, как объект класса (куча) взаимодействует с myInt публичной переменной (стеком)?

Кто-нибудь может объяснить, пожалуйста ..

Ответы [ 5 ]

4 голосов
/ 09 марта 2010

Боюсь, ваше предположение неверно, если вы говорите о .NET. Типы значений хранятся в стеке, только когда они не являются частью экземпляра ссылочного типа. То есть ваш myInt хранится как часть любого экземпляра A в куче.

1 голос
/ 09 марта 2010

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

Задайте себе вопрос: какая часть ссылочного типа хранится в куче? Что за память? Из чего состоит ссылочный тип?

- В первую очередь он состоит из памяти переменных-членов. 1) Это данные, которые хранятся в куче. Так что в вашем примере это будет переменная myInt.

Типы значений только хранятся в стеке (как вы предполагали), если они являются локальными переменными внутри метода или их параметрами. Для этого существует стек: хранение локальных переменных и параметров (и указателей возврата вызовов функций).


1) А также иногда так называемый vtable, который хранит адреса виртуальных функций. Но это не имеет отношения к этому вопросу.

0 голосов
/ 03 октября 2010

Я сделаю все мои разговоры 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;
   }

Вот детали выделения памяти:

  1. obj, являющийся ссылкой на объект - стек
  2. Экземпляр Myclass, на который указывает переменная obj - Управляемая куча
  3. Тип значения Переменная-член i - управляемая куча
  4. dst - ссылка на объект набора данных - управляемая куча
  5. Экземпляр набора данных, на который указывает переменная dst - Управляемая куча
  6. Параметр типа значения j - стек
  7. dst2, который является ссылкой на объект набора данных - стек
  8. Экземпляр набора данных, на который указывает переменная dst2 - Управляемая куча
  9. Тип значения Локальная переменная k - стек
  10. dst3, который является ссылкой на объект набора данных - стек
  11. Экземпляр набора данных, на который указывает dst3 - Управляемая куча

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

Снова цитирую :

теперь, как объект класса (куча) взаимодействует с публичной переменной myInt (Стек)

Первое, что я хочу добавить, это то, что объект и переменные не взаимодействуют. Это код (исполняемые инструкции IL, присутствующие в методе), которые взаимодействуют с открытыми переменными экземпляра класса (он же объект).

Смотрите, CLR загружает тип только один раз в память. Таким образом, все инструкции IL, соответствующие вашему методу Display, будут находиться в центре памяти независимо от количества экземпляров класса A, которые вы создаете в своей программе. Только экземпляры (содержащие данные переменных-членов) класса A будут занимать другое место (точнее, адрес памяти) в куче.

Поэтому, когда выполняется инструкция IL для метода Display, он имеет указатель на this, который является ссылкой на текущий экземпляр объекта в куче. this ссылка различна для разных экземпляров объекта. this всегда указывает на начальный макет адреса памяти вашего текущего экземпляра объекта. Оттуда требуется смещение, чтобы добраться до адреса памяти, где находится myInt, чтобы получить доступ / изменить его.

Надеюсь, это поможет вам создать мысленную модель того, как код C # работает под капотом в среде CLR.

0 голосов
/ 09 марта 2010

Если вы создаете экземпляр class A, скажем, A obj=new A();, объект типа A создается в куче. Этот объект в куче составляет экземпляр varialbe myInt также в куче вместе с другими переменными-членами, если они были. И вы ссылаетесь на этот объект в куче с помощью ссылочной переменной obj, которая будет в стеке. Например,

class Mainclass{
main(){
A obj=new A();
//......all other code......
}
}

EDIT:

Обязательно для разработчиков .net:
Память в .Net и Ссылка и значения .

0 голосов
/ 09 марта 2010

Как правило, поиск переменных - это задача компилятора.

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