Как точно работают статические поля внутри?

Скажем, у вас есть класс,

class Foo
{
    public static bar;
}

Когда вы говорите:

new Foo();

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

... и когда вы снова скажете:

new Foo(); 

... ну, теперь у вас есть другое пространство для объекта.

Однако, где именно находится статическое поле?

Я действительно пытаюсь научиться:

Как ссылки на объекты ссылаются на одно и то же поле объектов, на которые они ссылаются?

Ответы

Ответ 1

Хотя точные детали системы типов зависят от реализации, позвольте мне углубиться в более подробно, чем просто заявить, что это зависит, и вам все равно. Я опишу, как он примерно работает в реализации Microsoft (.NET) в соответствии с книгой CLR через С# Джеффри Рихтером, а статья См. Как CLR создает объекты времени выполнения Hanu Kommalapati и др. (оригинальная версия MSDN Май 2005 г.).


Скажем, у вас есть класс:

class Foo
{
    // Instance fields
    string myBar = "Foobar";
    int myNum;

    // Static fields
    static string bar = "Foobar";
    static int num;
}

Foo myFoo = new Foo();
Type typeOfFoo = typeof(Foo);

Где живут экземпляры?

Всякий раз, когда вы говорите new Foo(), пространство выделяется и инициализируется для экземпляра объекта, и вызывается конструктор. Этот экземпляр показан как экземпляр Foo на изображении ниже. Например, экземпляр содержит только поля экземпляра класса (в этом случае myBar и myNum), а для объектов, выделенных в куче, два дополнительных поля, используемые средой выполнения (Sync block index и Type handle). Указатель типа является указателем на объект Type, который описывает тип экземпляра, в этом случае тип Foo.

Когда вы снова произнесете new Foo(), будет выделено новое пространство, которое снова будет содержать пробел для полей экземпляра этого типа. Как вы можете видеть, поля экземпляра связаны с экземплярами объектов.

Среда выполнения помещает каждое поле экземпляра с фиксированным смещением от начала данных объекта. Например, myBar может жить со смещением +4. Адрес поля экземпляра - это просто адрес объекта плюс смещение поля.

Где живут статические поля?

Статические поля в С# и Java не связаны ни с каким экземпляром объекта, но с типом. Классы, структуры и перечисления являются примерами типов. Только один раз (для каждого типа) - это некоторое пространство, выделенное для хранения значений статических полей. Было бы целесообразно выделить пространство для статических полей в структуре Type, которая описывает тип, так как существует только один объект Type для каждого типа. Это подход, используемый С# и Java.

Объект Type 1 создается, когда тип загружается средой выполнения. Эта структура содержит все виды информации, необходимые для того, чтобы среда выполнения могла выделять новые экземпляры, методы вызова и выполнять кастинг, среди прочего. Он также содержит пространство для статических полей, в этом случае bar и num.

Время выполнения помещает каждое статическое поле с некоторым смещением от начала данных типа. Это различно для каждого типа. Например, bar может жить со смещением +64. Адрес статического поля - это адрес объекта Type плюс смещение поля. Тип статически известен.

Displays some object structures, and their relationships.

1). В Microsoft.NET несколько разных структур описывают тип, например, метод MethodTable и структуры EEClass.

Ответ 2

Это полностью зависит от рассматриваемой реализации. Для С# и Java среда выполнения позволяет определить, где хранить память для переменной. Для C и большинства скомпилированных языков компилятор делает это определение.

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

Ответ 3

Это сильно варьируется от языка к языку и может даже сильно варьироваться от платформы к платформе...

Например, на стороне .NET статические члены "связаны" с управляющим определением EEClass, которое может быть выделенным кучей OR a "где угодно", назначенным членом (С# spec не указывает поведение кучи/стека, это деталь реализации VM)

Ответ 4

Там могут быть исключения, но для ссылочных типов new -keyword обычно создает объект во внутренней структуре данных, называемой "куча". Куча управляется CLR (Common Language Runtime). Не имеет значения, есть ли у вас статический или экземплярный элемент или локальная переменная.

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

Это только ссылка, статическая или нет; это различие не относится к ссылочному объекту (если только объект не является типом значения). Статический член, член экземпляра и локальная переменная могут ссылаться на один и тот же объект.

Ответ 5

Для Java объекты, на которые ссылаются статические поля, будут находиться в куче, как и другие объекты:

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

Поле будет инициализировано (если декларация содержит инициализацию), когда класс загружен, что происходит непосредственно перед первым вхождением любого одно из следующего:

  • создается экземпляр класса.
  • вызывается статический метод, объявленный классом.
  • назначено статическое поле, объявленное классом.
  • используется статическое поле, объявленное классом, и поле не является постоянной переменной (§4.12.4).

Доступ к статическому полю осуществляется с помощью двух специальных инструкций JVM, getstatic и putstatic. Но помимо этого различия статические поля похожи на нестатические поля.

Ответ 6

Im только знаком с С#, и это мое понимание:

Затем ваша программа запускается, она загружает все связанные сборки в AppDomain. Когда загружается assambly, вызываются все статические конструкторы, включая статические поля. Они будут жить там, и единственный способ их разгрузить - выгрузить AppDomain.

Ответ 7

Статические члены и константы хранятся в куче. В отличие от объектов в куче, которые могут получить сбор мусора, члены Static и константы остаются до тех пор, пока Appdomain не будет разорван, поэтому нужно быть осторожным при работе со статическими полями

Ответ 8

Статические переменные относятся к классу не к объекту, поэтому в памяти есть только один bar, даже если вы инициализируете тысячи моментов Foo.

Ответ 9

Это зависит от языка к языку или дизайнера языка. Если я говорю о Java, статические члены хранятся в области "Метод" JVM, и все объекты связаны с ними. Еще важнее знать, что мы можем получить доступ к элементу статических данных, не создавая объект класса. Это означает, что выделение памяти статическим членам данных не зависит от создания объекта этого класс.

Ответ 10

По спецификации статические переменные хранятся в Constant Pool. JVM хранит эту информацию в Постоянном поколении.

Ответ 11

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

так что в основном это похоже на

+++++++++++++++++++++++++++++++++++++
+ DATA Segment
+   -static vars
+   
+----------------------------------
+  instances | instances | instances|
+            |           |          |

здесь единая область разделяется между экземплярами.

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