Структура и механизм JVM

Java задняя часть JVM переводчик

1. Что такое JVM

Виртуальная машина Java (Java Virtual Machine), виртуальная машина, которая может запускать байт-код, интерпретировать байт-код в машинные инструкции под разными ОС, с jvm язык java не нужно перекомпилировать при работе на разных платформах, т.е. независимость от платформы.

Принцип: Скомпилированные программные инструкции Java не выполняются напрямую на ЦП аппаратной системы, а выполняются JVM. JVM скрывает информацию, относящуюся к конкретной платформе, так что компилятору языка Java нужно только сгенерировать целевой байт-код (. need.

1、以 Java 为例,我们在文本编译器写好了 Java 代码,交由「编译器」编译成 Java Bytecode。然后 Bytecode 交由 JVM 来执行,这时候 JVM 充当了「解释器」的角色,在解释 Bytecode 成 Machine Code 的同时执行它,返回结果。 2、以 BASIC 语言(早期的可以由计算机直译的语言)为例,通过文本编译器编写好,不用经历「编译」的过程,就可以直接交由操作系统内部来进行「解释」然后执行。 3、以 C 语言为例,我们在文本编译器编写好源代码,然后运行 gcc hello.c 编译出 hello.out 文件,该文件由一系列的机器指令组成的机器码,可以直接交由硬件来执行。

1.2 Процесс запуска JVM

jvm.cfg
-server KNOWN
-client IGNORE
-hotspot ALIASED_TO -server
-classic WARN
-native ERROR
-green ERROR

KNOWN означает существование, IGNORE означает отсутствие, ALIASED_TO означает присвоение псевдонима другой JVM. WARN означает найти альтернативу, когда она не существует, ERROR означает, что она не существует и выдает исключение

1.3 Преимущества JVM, другие языки выбирают для реализации в JVM

В настоящее время существует множество языков, которые выбирают jvm, например Scala, Kotlin, Ceylon, Xtend, Groovy, Clojure;
После длительного периода разработки JVM стала зрелой и завершенной. Полный язык включаетинтерфейс, оптимизация, серверная часть, среда выполнения, библиотекаJVM заботится о последних четырех.

  • Очень экономично реализовать кроссплатформенность. Компилятору языка нужно только вывести байт-код JVM. Кроссплатформенность требует много работы, например, много усилий уходит на оптимизацию под разные платформы и процессоры просто путем независимой разработки и генерации нативного кода.
  • Отличная производительность JIT (Just-In-Time Compilation) JVM. JIT может записывать характеристики работы программы на лету и выполнять на ее основе множество оптимизаций (отличная производительность корпоративных приложений Java в значительной степени зависит от этого). JIT С тех пор как HotSpot JVM была выпущена с Java 1.2, производительность JVM JIT продолжала улучшаться и является бесспорным успехом. Использование JVM в качестве целевой платформы означает, что большая часть работы по оптимизации производительности может быть передана JVM на аутсорсинг, что значительно снижает бюджет разработки гостевого языка.
  • Уже есть много зрелых примеров, и есть много опыта, на котором можно поучиться.
  • Как зрелая высокоуровневая операционная среда, JVM предоставляет множество сервисов, необходимых гостевому языку во время выполнения, таких как управление памятью (с лучшей в отрасли сборкой мусора и т. д.), в значительной степени избегая дополнительной независимой разработки.
  • Существует множество независимых реализаций JVM, а также несколько поставщиков, которые продолжат ее продвигать Данные полны, а сообщество огромно.
  • Сообщество Java имеет большое количество зрелых библиотек, и, вообще говоря, другие языки, работающие на JVM, разрабатывают специальный «мост», чтобы помочь напрямую использовать библиотеки Java, что является хорошим аргументом в пользу потенциальных клиентов.
  • Java имеет достойные инструменты и среды разработки. Многие языки, ориентированные на JVM, рассмотрят возможность реализации на языке Java (по крайней мере, на этапе начальной загрузки).

2. Структура JVM

JVM = загрузчик классов загрузчик классов + исполнительный механизм исполнительный механизм + область данных времени выполнения область данных времени выполнения

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

Вот краткое введение в роль каждого компонента

  • подсистема загрузки классов: Каждая виртуальная машина Java состоит из подсистемы загрузчика классов (class loader subsystem), отвечающей за загрузку типов (классов и интерфейсов) в программу и присвоение уникального имени. Каждая виртуальная машина Java имеет механизм выполнения (execution engine), отвечающий за выполнение инструкций, содержащихся в загруженном классе.

  • Для выполнения программы требуется определенный объем памяти, такой как байт-код, другая дополнительная информация о загруженном классе, объекты в программе, параметры метода, возвращаемые значения, локальные переменные, промежуточные обрабатываемые переменные и так далее. Виртуальная машина Java хранит всю эту информацию вобласть данныхсередина. Хотя область данных включена в реализацию каждой виртуальной машины Java, область данных очень абстрактна в спецификации виртуальной машины Java. Многие архитектурные детали остаются на усмотрение разработчика виртуальной машины Java. Структура памяти различных реализаций виртуальных машин Java сильно различается. Некоторые реализации могут использовать много памяти, а другие — очень мало; некоторые реализации могут использовать виртуальную память, а другие — нет. Эта относительно усовершенствованная спецификация памяти виртуальной машины Java позволяет реализовать виртуальную машину Java на широком диапазоне платформ.

  • Часть области данных является общей для всей программы, а другие части управляются отдельными потоками. Каждая виртуальная машина Java содержитобласть методаа такжекуча, все они являются общими для всей программы. После того как виртуальная машина Java загрузит и проанализирует класс, информация, извлеченная из файла класса, сохраняется в области методов. Объекты, созданные во время выполнения программы, хранятся в куче. Когда создается поток, ему выделяется только собственный регистр ПК «регистр ПК» (счетчик программ) и стек Java (стек Java). Когда поток не использует собственный метод, регистр PC содержит следующую инструкцию, выполняемую потоком. Стек Java сохраняет состояние потока при вызове метода, включая локальные переменные, параметры вызывающего метода, возвращаемые значения и обработанные промежуточные переменные. Состояние при вызове собственных методов хранится в стеках собственных методов, возможно, в регистрах или другой памяти, не зависящей от платформы.

  • Стек JavaОн состоит из кадров стека (или кадров). Блок стека содержит состояние вызова метода Java. Когда поток вызывает метод, виртуальная машина Java помещает новый блок в стек Java, а когда метод завершается, виртуальная машина Java извлекает и отбрасывает соответствующий блок.

  • Виртуальная машина Java не использует регистры для хранения промежуточных результатов вычислений, а использует стек Java для хранения промежуточных результатов. Это делает инструкции виртуальной машины Java более компактными и простыми для реализации на устройстве без регистров.

2.1. Переводчик

Под интерпретатором можно понимать программу, которая преобразует язык высокого уровня в другой язык. В JVM интерпретатор преобразует файл байт-кода в машинный двоичный язык, чтобы наш компьютер мог выполнить его напрямую. Однако, поскольку каждый раз, когда программа запускается, ее необходимо преобразовать на другой язык перед запуском, поэтому можно представить себе скорость работы интерпретатора, что также создает впечатление, что скорость работы java относительно низкая.

По сути, каждая программа является «описанием» машины, а интерпретатор «симулирует» работу машины, то есть «вычисляет». Так что в некотором смысле интерпретатор является сущностью вычислений.

Интерпретаторы обычно являются «рекурсивными программами». Причина его рекурсивности заключается в том, что структуры данных (программы), с которыми он работает, сами по себе являются «рекурсивно определенными» структурами.

После версии java1.2 современная виртуальная машина HotSpot имеет не только встроенный интерпретатор, но и расширенный встроенный компилятор JIT (Just In Time Compiler). компиляторы во времени могут взаимодействовать друг с другом, дополнять друг друга

2.2. ТОЧНО

Виртуальная машина HotSpot использует технологию обнаружения горячего кода: находит наиболее компилируемый код с помощью счетчика и сообщает JIT, чтобы он скомпилировал его в единицах методов. Если метод вызывается часто, срабатывает стандартная компиляция, если в методе много циклов, срабатывает действие замещающей компиляции в стеке. HotSpot не нужно ждать вывода собственного кода перед выполнением программы, что снижает нагрузку на компиляцию «точно в срок» и помогает применять больше методов оптимизации кода. Вывод высококачественного собственного кода ОС.

Почему виртуальная машина HotSpot использует архитектуру, в которой сосуществуют интерпретатор и компилятор?

Хотя не все виртуальные машины Java используют архитектуру, в которой сосуществуют интерпретаторы и компиляторы, многие популярные коммерческие виртуальные машины (например, HotSpot) содержат и интерпретаторы, и компиляторы. И интерпретаторы, и компиляторы имеют свои преимущества: когда программу нужно быстро запустить и выполнить, интерпретатор может сыграть роль первым, сэкономив время компиляции и немедленно выполнив ее. После запуска программы, с течением времени, компилятор постепенно вступает в игру.После того, как все больше и больше кодов скомпилировано в собственные коды, может быть достигнута более высокая эффективность выполнения. Когда ограничение ресурсов памяти в среде выполнения программы относительно велико (например, в некоторых встроенных системах), для экономии памяти можно использовать интерпретатор, в противном случае для повышения эффективности можно использовать компилятор. Кроме того, если после компиляции возникает «редкая ловушка», можно вернуться к интерпретируемому выполнению с деоптимизацией.

время компиляции

Абстрактно выполнение интерпретатора выглядит так:

Введенный код -> [выполнение интерпретатора интерпретатора] -> результат выполнения

И если вы хотите JIT-компилировать, а затем выполнить, абстрактное представление:

Входной код -> [компиляция компилятора] -> скомпилированный код -> [выполнить] -> результат выполнения

Сказать, что JIT быстрее, чем интерпретация, на самом деле означает, что «выполнение скомпилированного кода» быстрее, чем «интерпретация и выполнение интерпретатором», а не то, что действие «компилировать» быстрее, чем действие «интерпретация». Какой бы быстрой не была JIT-компиляция, она хотя бы немного медленнее, чем интерпретация и однократное выполнение, и для получения конечного результата выполнения необходимо пройти процесс «выполнения скомпилированного кода». Таким образом, для кода с однократным выполнением интерпретируемое выполнение всегда быстрее, чем выполнение, скомпилированное JIT. Как это считается «кодом, выполненным только один раз»? Грубо говоря, при одновременном выполнении следующих двух условий строго "выполняется только один раз"

1. Вызывается только один раз, например, инициализатор класса (инициализатор класса, ())

2. Нет цикла

Можно сказать, что компиляция JIT и выполнение кода, который выполняется только один раз, стоят потерь. Для кода, который выполняется лишь небольшое количество раз, повышение скорости выполнения, вызванное JIT-компиляцией, не обязательно компенсирует накладные расходы, вызванные первоначальной компиляцией.

Только для часто исполняемого кода JIT-компиляция может гарантировать положительный эффект. Накладные расходы на компиляцию Для общих методов Java обычно размер скомпилированного кода имеет коэффициент раздувания в 10 раз по сравнению с размером байт-кода. Как и накладные расходы времени, упомянутые выше, накладные расходы пространства здесь также.Стоит компилировать только код, который часто выполняется.Если все коды скомпилированы, пространство, занимаемое кодом, будет значительно увеличено, что приведет к «взрыву кода». Это также объясняет, почему некоторые JVM предпочитают не всегда выполнять JIT-компиляцию, а предпочитают использовать гибридный механизм выполнения интерпретатора + JIT-компилятора.

Почему виртуальная машина HotSpot реализует два разных интерактивных компилятора?

В виртуальной машине HotSpot есть два встроенных компилятора реального времени: клиентский компилятор и серверный компилятор, называемые компиляторами C1 и C2, которые используются на стороне клиента и на стороне сервера соответственно. В текущей основной виртуальной машине HotSpot по умолчанию используется интерпретатор для работы напрямую с одним из компиляторов. Какой компилятор использует программа, зависит от режима, в котором работает виртуальная машина. Виртуальная машина HotSpot автоматически выбирает режим работы в соответствии со своей версией и аппаратной производительностью хост-машины.

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

Разработчики могут явно указать, какой тип JIT-компилятора использует виртуальная машина Java во время выполнения с помощью следующей команды:

-client:指定Java虚拟机运行在Client模式下,并使用C1编译器;

-server:指定Java虚拟机运行在Server模式下,并使用C2编译器。

Продукты JVM, кратко изложенные в вики https://en.wikipedia.org/wiki/Сравнение_Java_virtual_machines

3. Просмотр файлов байт-кода через jclasslib

После экранирования байт-кода легко увидеть, как загружаются методы init и add.

iload_1 从局部变量0中装载int类型值
iload_2 从局部变量0中装载int类型值
iadd 执行int类型的加法
ireturn 从方法中返回int类型的数据

1. [Обсуждение] [HotSpot VM] JIT-компиляция и выполнение нативной http://hllvm.group.iteye.com/group/topic/39806

2. Процесс компиляции компилятора JVM http://blog.csdn.net/tingfeng96/article/details/52261219

3. Моментальная компиляция JVM (JIT) http://blog.csdn.net/sunxianghuang/article/details/52094859