Где разрешенная ссылка (что означает прямой адрес памяти против символьной ссылки) хранится в JVM после разрешения? - PullRequest
0 голосов
/ 04 декабря 2018

Я изучал JVM (особенно версию JDK 8) и, изучая связи классов, я не выяснил, где адрес прямой памяти, который был определен из символьной ссылки в резолюции.

Естьнесколько видов разрешений, таких как тип (класс / интерфейс), поле, метод и т. д., но я просто делаю пример класса для простого объяснения.

В спецификации JVM есть несколько слов.

5.1 Пул постоянных времени выполнения Виртуальная машина Java поддерживает постоянный пул для каждого типа (§2.5.5), структуру данных времени выполнения, которая служит многим целям таблицы символовтрадиционная реализация языка программирования.Таблица constant_pool (§4.4) в двоичном представлении класса или интерфейса используется для создания пула констант во время выполнения при создании класса или интерфейса (§5.3). Все ссылки в пуле постоянных времени выполнения изначально являются символическими.

В спецификации сказано, что все ссылки сначала являются символическими.

Вот пример Mainclass.

public class Main {
    public static void main(String[] args) {
        Object obj = new Object();
    }
}

Вот информация о пуле констант класса Main.

Constant pool:
#1 = Methodref          #2.#12         // java/lang/Object."<init>":()V
#2 = Class              #13            // java/lang/Object
#3 = Class              #14            // Main
#4 = Utf8               <init>
#5 = Utf8               ()V
#6 = Utf8               Code
#7 = Utf8               LineNumberTable
#8 = Utf8               main
#9 = Utf8               ([Ljava/lang/String;)V
#10 = Utf8               SourceFile
#11 = Utf8               Main.java
#12 = NameAndType        #4:#5          // "<init>":()V
#13 = Utf8               java/lang/Object
#14 = Utf8               Main
{
  public Main();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method     java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 1: 0

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: new           #2                  // class java/lang/Object
         3: dup
         4: invokespecial #1                  // Method java/lang/Object."<init>":()V
         7: astore_1
         8: return
      LineNumberTable:
        line 3: 0
        line 4: 8
}
SourceFile: "Main.java"

4.4.1 Структура CONSTANT_Class_info
Структура CONSTANT_Class_info используется для представлениякласс или интерфейс>:
CONSTANT_Class_info {
u1 tag;
u2 name_index;
}

Здесь класс Object указывается в методе main класса Main.В классе Main класс Object никогда не вызывается. (Когда команда java Main просто исполняется;) Это означает, что Object Class entry(here, #2: CONSTANT_Class_info structure.) в пуле констант Main имеет name_index # 13.# 13 - это структура CONSTANT_Utf8_info, содержащая имя класса Object, а # 13 - символическая ссылка на класс Object. (Честно говоря, я не уверен, что эта запись пула констант Utf8 является символической ссылкой # 2 (запись пула классов объекта))

Когда механизм исполнения JVM просто выполняет байт-код, который имеет ссылку на класс Object (в данном разделе 0: new #2), # 2 ссылается на # 13 (символьная ссылка).Таким образом, его необходимо разрешить по прямому адресу класса объекта в области методов в JVM.И разрешение класса происходит.

Вот вопрос. Я читал и искал спецификации JVM, а также блоги, статьи, но не смог найти, где разрешен прямой адрес памяти для символическогосправочные хранилища в JVM.

Я нашел некоторую информацию в блоге , где сказано:

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

Сказано, заменено .В записи константы # 2 символическая ссылка класса Object сохраняется в поле name_index (тип u2) структуры CONSTANT_Class_info.

Значение поля name_index, измененное на прямой адрес памяти класса объекта (возможно, впостоянный пул времени выполнения для объекта clsas в области метода) ????

Если нет, где хранится прямой адрес?

Пожалуйста, дайте мне ответ.Спасибо.

1 Ответ

0 голосов
/ 06 декабря 2018

В спецификации не указано, где JVM хранит разрешенные записи константного пула.Это детали реализации.

В HotSpot JVM постоянный пул находится в Metaspace.Он состоит из двух связанных массивов: массив тегов и массив значений.Теги описывают типы соответствующих значений.Но это , а не те же теги, которые определены в JVMS §4.4 .JVM заполняет постоянный пул своими собственными тегами на этапе анализа файла класса.

Существует 4 различных типа записи постоянного пула, которые обозначают ссылку на класс Java:

  • JVM_CONSTANT_ClassIndexизначально содержит целочисленный индекс для записи Utf8 в постоянном пуле с именем класса.
  • JVM_CONSTANT_UnresolvedClass.После полной загрузки исходного содержимого пула констант JVM меняет теги JVM_CONSTANT_ClassIndex на JVM_CONSTANT_UnresolvedClass и заменяет соответствующие записи cp символическими именами.
  • JVM_CONSTANT_UnresolvedClassInError означает то же самое, что и JVM_CONSTANT_UnresolvedClass, но обозначаетчто попытка разрешения класса не удалась.
  • JVM_CONSTANT_Class - это необработанный адрес внутреннего представления разрешенного класса.

Итак, ваше предположение было верным: при постоянном разрешении пулаHotSpot JVM изменяет записи cp на месте и изменяет соответствующие теги cp.То есть JVM_CONSTANT_UnresolvedClass становится JVM_CONSTANT_Class, и символическая ссылка заменяется прямым адресом прямо в том же массиве постоянных значений пула.

Вы можете найти реализацию в ConstantPool :: klass_at_impl.

...