Intereting Posts
PHP Перенаправление на новую страницу после отправки формы Как фильтровать пользователя в LDAP PHP Значение mysql по столбцу, сгруппированное по значению столбца Комбинируя маршруты Laravel Codeigniter – как включить динамический файл javascript в представлении Подключение к базе данных с ODBC приводит к предупреждению и непечатанию Неустранимая ошибка: исключить исключение «Parse \ ParseException» с сообщением «Ошибка SSL-сертификата: невозможно получить сертификат локального эмитента» PHP, передающий несколько переменных на нескольких страницах CSS не загружается на одном из моих маршрутов / представлений Как добавить запятые к номерам в PHP Хорошая идея запустить PHP-файл в течение нескольких часов, как cronjob? Как преобразовать json закодированный массив PHP в массив в Javascript? Как строго проверить сайт? PDO MySQL: используйте PDO :: ATTR_EMULATE_PREPARES или нет? ContextErrorException после создания пакета в Symfony

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

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

class Foo { public static bar; } 

Когда ты говоришь:

 new Foo(); 

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

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

 new Foo(); 

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

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

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

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

Solutions Collecting From Web of "Как точно работают статические поля внутри?"

Хотя точные детали системы типов зависят от реализации, позвольте мне углубиться в более подробно, чем просто заявить, что это зависит, и вам все равно . Я опишу, как он примерно работает в реализации Microsoft (.NET) в соответствии с книгой CLR через C # Джеффри Рихтером и статьей « Как CLR создает объекты времени выполнения » Hanu Kommalapati и др. ( оригинальная версия MSDN May 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. Адрес поля экземпляра – это просто адрес объекта плюс смещение поля.

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

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

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

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

Отображает некоторые структуры объектов и их отношения.

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

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

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

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

Например, на стороне .NET статические члены «связаны» с управляющим определением EEClass , которое может быть выделенным кучей ИЛИ членом «где угодно» (спецификация C # не указывает поведение кучи / стека, это деталь реализации VM)

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

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

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

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

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

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

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

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

Я только знаком с C #, и это мое понимание этого:

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

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

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

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

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

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

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

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

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

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