2012-04-18 2 views
49

В настоящее время я пытаюсь углубиться в спецификацию виртуальной машины Java. Я читал Inside the JVM book online, и есть одна запутанная абстракция, которую я не могу понять: Constant Pool. вот выдержка из книги:Какова цель Java Constant Pool?

Для каждого типа, который он загружает, виртуальная машина Java должна хранить постоянный пул. Постоянный пул - это упорядоченный набор констант, используемых типом, включая литералы (строковые, целочисленные и константы с плавающей запятой) и символические ссылки на типы, поля и методы. Записи в пуле констант ссылаются на индекс, подобно элементам массива. Поскольку он содержит символические ссылки на все типы, поля и методы, используемые типом, постоянный пул играет центральную роль в динамической компоновке программ Java.

У меня есть несколько вопросов об упомянутых выше и CP в целом:

  1. Есть ли CP, расположенный в .class файлах для каждого типа?
  2. Что означает автор «символическая ссылка»?
  3. Какова цель постоянного пула, на простом английском языке?

ответ

51

Я думаю, что понимание того, как кадр будет построен с использованием диаграммы, поможет.

enter image description here

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

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

Код C/C++ обычно скомпилирован в объектный файл, а затем несколько объектных файлов связаны между собой, чтобы использовать полезный артефакт, такой как исполняемый файл или dll. Во время фазы связывания символические ссылки в каждом объектном файле заменяются фактическим адресом памяти относительно окончательного исполняемого файла. В Java эта фаза связывания выполняется динамически во время выполнения.

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

Для получения более подробной информации, ссылка на James Blooms JVM Internals.

+0

«Когда компилируется класс Java ...»? Не является ли файл .class уже скомпилированным кодом Java? –

+1

Да, файл .java становится компилированным файлом .class. –

+0

ссылка не работает –

6

Что такое цель постоянного пула, на простом английском языке?

СР представляет собой область памяти, очень уникальные постоянные значения сохраняются для уменьшения избыточности:

System.err.println("Hello"); 
System.out.println("Hello"); 

В СРЕ есть только один объект строка «Hello» и компилятор заменители в обеих линиях к такой же ссылка. Файл .class содержит только одну строку Hello. (То же самое для других типов).

Есть ли CP, расположенный в файле .Class для каждого типа?

Да Посмотрите здесь: http://en.wikipedia.org/wiki/Java_class_file

+0

ли вы расширить немного больше символических ссылок, возможно? Я думаю, что это самая важная часть CP – Bober02

63

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

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

Например, следующий код

System.out.println("Hello, world!"); 

производит следующие байты-код (javap выхода)

0: getstatic  #2; //Field java/lang/System.out:Ljava/io/PrintStream;    
3: ldc  #3; //String Hello, world!             
5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 

#n здесь находятся ссылки на постоянная бассейн. #2 является символической ссылкой на поле System.out, #3 является строкой Hello, world! и #4 является символической ссылкой на метод PrintStream.println(String).

Как вы можете видеть, символические ссылки не только имена - например, символическая ссылка на метод также содержит информацию о его параметрах (Ljava/lang/String;) и тип возвращаемого значения (V означает void).

Вы можете проверить постоянный пул класса, запустив javap -verbose для этого класса.

+0

@ axtavt- wow! приятный информация. выглядит как маленькая опечатка рядом с "# 3 является символической ссылкой на PrintStream .." should'nt это будет # 4 –

+0

@mashit: Да, исправлено. – axtavt

+0

Но что означает «L» в «Ljava/lang/String;» ? – JackWM

1

Пусть дать пример сначала понять, что строковая константа бассейн означает

public class StringConstantPool { 
     public static void main(String[] args) { 
      String s = "prasad"; 
      String s2 = "prasad"; 

      System.out.println(s.equals(s2)); 
      System.out.println(s == s2); 
     } 
    } 

выход будет

true 

true 

, что случилось здесь, шаг за шагом

1- класс загружается при вызове JVM.

2 JVM будет искать все строковые литералы в программе.

3- Во-первых, он находит переменную с, которая относится к буквального «прасад» и он будет создан в памяти

4- Ссылка для буквального «прасад» будет помещен в постоянную память пула.

5- Затем он находит другую переменной s2, который со ссылкой на ту же строку буквального «Прасад».

Теперь, когда JVM уже нашел строковый литерал «прасад», оба переменных S и s2 Виля относится к одному объекту т.е. «ПРАСАД».

enter image description here

Я надеюсь, что это будет полезно

читать далее http://www.journaldev.com/797/what-is-java-string-pool

+2

Существует не такая вещь, как «String constant pool». Существует постоянный пул, который существует в каждом файле класса, и существует «String pool» интернированных строк, которые существуют для JVM. – Keenle

+0

да, здесь я имел в виду пул строк, спасибо за комментарий –

Смежные вопросы