Где разрешенная ссылка (что означает прямой адрес памяти против символьной ссылки) хранится в JVM после разрешения?

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

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

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

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

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

Вот пример основного класса.

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

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

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;
u2 name_index;
}

Здесь класс Object упоминается в методе main класса Main. В главном классе класс Object никогда не упоминается.(Когда команда java Main просто извинился;) это значит Object Class entry(here, #2: CONSTANT_Class_info structure.) в постоянном пуле Майна есть 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 на прямой адрес памяти класса объекта (возможно, в пуле постоянных времени выполнения для класса объекта в области метода)????

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

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

1 ответ

Решение

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

В JVM HotSpot постоянный пул находится в 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 является необработанным адресом для внутреннего представления разрешенного класса.

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

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

Другие вопросы по тегам