Ссылочная переменная постоянного пула времени выполнения Java в кадре стека - PullRequest
0 голосов
/ 13 мая 2018

Согласно следующей ссылке кадр стека java содержит локальные переменные, стек операндов и ссылку на текущий пул констант класса.http://blog.jamesdbloom.com/JVMInternals.html

Также из Oracle «Структура JVM» Раздел 2.6.3.«Динамическое связывание - каждый кадр (§2.6) содержит ссылку на пул констант во время выполнения (§2.5.5) для типа текущего метода для поддержки динамического связывания кода метода».

Iтакже прочитал, что объект в куче также имеет указатель / ссылку на данные класса.https://www.artima.com/insidejvm/ed2/jvm6.html

Кадр стека будет содержать «текущую ссылку на пул констант класса», а также будет иметь ссылку на объект в куче, который, в свою очередь, также будет указывать на данные класса.Разве это не избыточно ??

Например.

public class Honda {
  public void run() {
    System.out.println("honda is running");
  } 
  public static void main(String[] args) {
  Honda h = new Honda();
  h.run(); //output honda is running
  }
}

Когда h.run () будет выполняться, jvm создаст новый кадр стека и нажмет h на кадре стека,h будет указывать на объект в куче, который в свою очередь будет иметь указатель на данные класса Honda.Кадр стека также будет иметь постоянную ссылку на текущий класс.Это правильно?Если нет, пожалуйста, пролите немного света на это.

Ответы [ 3 ]

0 голосов
/ 13 мая 2018

Кадр стека будет содержать «текущую ссылку на пул констант класса», а также ссылку на объект в куче, который, в свою очередь, также будет указывать на данные класса. Разве это не избыточно?

Вы пропустили предварительное условие этого утверждения, или вы его неправильно процитировали, или оно было просто неверно там, где вы его видели.

«Ссылка на объект в куче» добавляется только для нестатического метода и относится к скрытому параметру this.

Как сказано в разделе " Массив локальных переменных ":

Массив локальных переменных содержит все переменные, используемые во время выполнения метода, включая ссылку на this, все параметры метода и другие локально определенные переменные. Для методов класса (то есть статических методов) параметры метода начинаются с нуля, однако для метода экземпляра нулевой интервал зарезервирован для this.

Таким образом, для статических методов нет избыточности.

Может ли ссылка на постоянный пул быть исключена при наличии this? Да, но тогда потребуется другой способ определения местоположения ссылки на постоянный пул, требующий разных инструкций байт-кода, так что это будет другой тип избыточности.

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

0 голосов
/ 14 мая 2018

Здесь есть два момента. Во-первых, есть static методы, которые вызываются без ссылки this. Во-вторых, фактический класс экземпляра объекта не обязательно является декларирующим классом метода, код которого мы фактически выполняем. Назначение ссылки на постоянный пул - разрешить разрешение символьных ссылок и загрузку констант, на которые ссылается код. В обоих случаях нам нужен постоянный пул класса, содержащего исполняемый в данный момент код, даже если метод может быть унаследован фактическим классом ссылки this (в случае метода private, вызванного другим унаследованным методом, у нас есть метод, вызываемый с this экземпляром класса, который формально даже не наследует метод).

Может даже случиться, что текущий исполняемый код содержится в интерфейсе, поэтому у нас никогда не бывает его экземпляров, но все равно есть файл класса с постоянным пулом, который должен быть доступен при выполнении кода. Это относится не только к Java 8 и новее, которые допускают методы static и default в интерфейсах; более ранние версии также могут нуждаться в выполнении метода <clinit> интерфейса для инициализации его полей static.

Кстати, даже если метод экземпляра вызывается со ссылкой на объект, связанный с this в его первой локальной переменной, для инструкций байт-кода не требуется сохранять его там. Если в этом нет необходимости, он может быть перезаписан произвольным значением, повторно используя слот переменной для других целей. Это не исключает того, что последующим инструкциям необходим постоянный пул, который, как уже было сказано, не обязательно должен принадлежать фактическому классу this.

Конечно, ссылка на пул в любом случае является логической конструкцией. Реализации могут преобразовывать код для использования общего пула или вообще не требовать его, когда все ссылки уже разрешены и т. Д. После встраивания у кода может даже не быть выделенного стекового фрейма.

0 голосов
/ 13 мая 2018

Разве это не избыточно?

Может быть, это избыточно для экземпляров методов и конструкторов.

Он не является избыточным для статических методов или псевдо-методов инициализации класса.


Также возможно, что (предположительно) избыточная ссылка будет оптимизирована компилятором JIT. (Или, может быть, это не оптимизировано ... потому что они пришли к выводу, что избыточность приводит к более быстрому выполнению в среднем .) Или, возможно, фактическая реализация JVM 1 просто отличается.

Имейте в виду, что спецификация JVM описывает идеализированный кадр стека. Реальная реализация может отличаться ... при условии, что ведет себя так, как указано в спецификации.


С точки зрения @ EJP о нормативности, единственными нормативными ссылками на Java являются спецификации JLS и JVM и Javadoc для библиотеки классов. Вы также можете обратиться к исходному коду самой JVM. Спецификации говорят, что должно произойти, а код (в некотором смысле) говорит, что делает Статья, которую вы можете найти в опубликованной газете или в веб-статье, не является нормативной и может быть неверной или устаревшей.


1 - Фактическая реализация может варьироваться от одной версии к другой или между поставщиками. Кроме того, я слышал о реализации JVM, где средство переписывания байт-кода преобразовывалось из стандартных байт-кодов в другой язык абстрактной машины во время загрузки класса. Это не было хорошей идеей с точки зрения производительности ... но это, безусловно, соответствовало духу спецификации JVM.

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