Как точно работают статические поля внутри?
Скажем, у вас есть класс,
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
плюс смещение поля. Тип статически известен.
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 "Область данных содержит глобальные и статические переменные, используемые программой, которые явно инициализируется значением."