виртуальная машина Java
Дизайнер | Сан Микросистемс |
---|---|
Биты | 32-битный |
Представлено | 1994 |
Версия | 20.0.1 [ 1 ] |
Тип | Складывать и регистрировать-регистрировать |
Кодирование | Переменная |
Ветвление | Сравнить и разветвить |
Порядок байтов | Большой |
Открыть | Да |
Регистры | |
общего назначения | Стек операндов для каждого метода (до 65 535 операндов) плюс локальные переменные для каждого метода (до 65 535) |
( Виртуальная машина Java JVM ) — это виртуальная машина , которая позволяет компьютеру запускать программы Java, а также программы, написанные на других языках , которые также скомпилированы в байт-код Java . JVM подробно описана в спецификации , которая формально описывает, что требуется от реализации JVM. Наличие спецификации обеспечивает совместимость программ Java в различных реализациях, поэтому авторам программ, использующим Java Development Kit (JDK), не нужно беспокоиться об особенностях базовой аппаратной платформы.
JVM Эталонная реализация разработана проектом OpenJDK как открытый исходный код и включает JIT-компилятор под названием HotSpot . Коммерчески поддерживаемые выпуски Java, доступные от Oracle, основаны на среде выполнения OpenJDK. Eclipse OpenJ9 — еще одна JVM с открытым исходным кодом для OpenJDK.
Спецификация JVM
[ редактировать ]Виртуальная машина Java — это абстрактный (виртуальный) компьютер, определенный спецификацией. Это часть среды выполнения Java. Используемый алгоритм сборки мусора и какая-либо внутренняя оптимизация инструкций виртуальной машины Java (их перевод в машинный код ) не указаны. Основная причина этого упущения состоит в том, чтобы не ограничивать разработчиков без необходимости. Любое Java-приложение может быть запущено только внутри некоторой конкретной реализации абстрактной спецификации виртуальной машины Java. [ 2 ]
Начиная с платформы Java Standard Edition (J2SE) 5.0, изменения в спецификации JVM разрабатываются в рамках процесса сообщества Java как JSR 924. [ 3 ] По состоянию на 2006 год [update], изменения в спецификации для поддержки изменений, предложенных в формате файла класса (JSR 202). [ 4 ] выполняются в виде сопровождения JSR 924. Спецификация JVM была опубликована в виде синей книги . [ 5 ] в предисловии которого говорится:
Мы предполагаем, что эта спецификация должна достаточно документировать виртуальную машину Java, чтобы сделать возможными совместимые реализации для «чистых помещений». Oracle предоставляет тесты, проверяющие правильную работу реализаций виртуальной машины Java.
Одна из JVM Oracle называется HotSpot; другой, унаследованный от BEA Systems , — JRockit . Oracle владеет торговой маркой Java и может разрешить ее использование для сертификации пакетов реализации как полностью совместимых со спецификацией Oracle.
Загрузчик классов
[ редактировать ]Одной из организационных единиц байт-кода JVM является класс . Реализация загрузчика классов должна иметь возможность распознавать и загружать все, что соответствует формату файлов классов Java . Любая реализация может распознавать и другие двоичные формы, помимо файлов классов , но она должна распознавать файлы классов .
Загрузчик классов выполняет три основных действия в строгом порядке:
- Загрузка: находит и импортирует двоичные данные для типа.
- Связывание: выполняет проверку, подготовку и (необязательно) разрешение.
- Проверка: обеспечивает правильность импортированного типа.
- Подготовка: выделяет память для переменных класса и инициализирует память значениями по умолчанию.
- Решение: преобразует символические ссылки типа в прямые ссылки.
- Инициализация: вызывает код Java, который инициализирует переменные класса их правильными начальными значениями.
В общем, существует три типа загрузчика классов: загрузчик классов начальной загрузки, загрузчик классов расширения и загрузчик классов системы/приложения.
Каждая реализация виртуальной машины Java должна иметь загрузчик классов начальной загрузки, способный загружать доверенные классы, а также загрузчик классов расширения или загрузчик классов приложений. Спецификация виртуальной машины Java не определяет, как загрузчик классов должен находить классы.
Архитектура виртуальной машины
[ редактировать ]JVM работает с определенными типами данных, как указано в спецификациях виртуальной машины Java. Типы данных можно разделить [ 6 ] на примитивные типы ( целые числа , с плавающей запятой, длинные и т. д.) и ссылочные типы. Более ранние JVM были только 32-битными машинами. long
и double
типы 64-битные поддерживаются изначально, но занимают две единицы памяти в локальных переменных кадра или стеке операндов, поскольку каждая единица имеет размер 32 бита. boolean
, byte
, short
, и char
все типы являются знаково-расширенными (кроме char
который расширяется до нуля ) и обрабатывается как 32-битные целые числа, так же, как и int
типы. Меньшие типы имеют лишь несколько специфичных для типа инструкций по загрузке, хранению и преобразованию типов. boolean
работает как 8-битный byte
значения, где 0 представляет false
и 1 представляющий true
. (Хотя boolean
рассматривается как тип с тех пор, как Спецификация виртуальной машины Java, второе издание, разъяснила эту проблему, в скомпилированном и исполняемом коде существует небольшая разница между boolean
и byte
за исключением искажения имен в сигнатурах методов и типа логических массивов. boolean
s в сигнатурах методов искажены как Z
пока byte
s искалечены как B
. Логические массивы имеют тип boolean[]
но используйте 8 бит на элемент, и JVM не имеет встроенной возможности упаковывать логические значения в битовый массив , поэтому, за исключением типа, они выполняют и ведут себя так же, как byte
массивы. Во всех других случаях использования boolean
тип фактически неизвестен JVM, поскольку все инструкции для работы с логическими значениями также используются для работы с byte
s.) Однако более новые версии JVM (OpenJDK HotSpot JVM) поддерживают 64-битную версию, поэтому вы можете использовать 32-битную или 64-битную JVM в 64-битной ОС. Основное преимущество запуска Java в 64-битной среде — большее адресное пространство. Это позволяет значительно увеличить размер кучи Java и увеличить максимальное количество потоков Java, что необходимо для определенных типов крупных приложений; однако при использовании 64-битной JVM производительность снижается по сравнению с 32-битной JVM.
В JVM есть куча со сбором мусора для хранения объектов и массивов. Код, константы и другие данные класса хранятся в «области метода». Область метода логически является частью кучи, но реализации могут обрабатывать область метода отдельно от кучи и, например, не выполнять сборку мусора. Каждый поток JVM также имеет свой собственный стек вызовов (для ясности называемый «стеком виртуальной машины Java»), в котором хранятся кадры . Новый кадр создается каждый раз при вызове метода и уничтожается при выходе из этого метода.
Каждый кадр предоставляет «стек операндов» и массив «локальных переменных». Стек операндов используется для операндов для выполнения вычислений и для получения возвращаемого значения вызываемого метода, а локальные переменные служат той же цели, что и регистры , а также используются для передачи аргументов метода. Таким образом, JVM является одновременно стековой машиной и регистровой машиной . На практике HotSpot исключает каждый стек, кроме собственного стека потоков/вызовов, даже при работе в интерпретируемом режиме, поскольку его интерпретатор шаблонов технически функционирует как компилятор.
Инструкции байт-кода
[ редактировать ]В JVM есть инструкции для следующих групп задач:
Целью является бинарная совместимость. Каждая конкретная операционная система хоста нуждается в собственной реализации JVM и среде выполнения. Эти JVM интерпретируют байт-код семантически одинаково, но фактическая реализация может отличаться. Более сложной, чем просто эмуляция байт-кода, является совместимая и эффективная реализация основного API Java , который должен быть сопоставлен с каждой операционной системой хоста.
Эти инструкции оперируют набором общих абстрактные типы данных , а не собственные типы данных любой конкретной архитектуры набора команд .
JVM-языки
[ редактировать ]Язык JVM — это любой язык, функциональность которого может быть выражена в виде допустимого файла класса, который может размещаться на виртуальной машине Java. Файл класса содержит инструкции виртуальной машины Java ( байт-код Java ) и таблицу символов, а также другую вспомогательную информацию. Формат файла классов — это двоичный формат, независимый от аппаратного обеспечения и операционной системы, используемый для представления скомпилированных классов и интерфейсов. [ 7 ]
Существует несколько языков JVM: как старые языки, портированные на JVM, так и совершенно новые языки. JRuby и Jython , пожалуй, самые известные порты существующих языков, т.е. Ruby и Python соответственно. Из новых языков, созданных с нуля для компиляции в байт-код Java, Clojure , Groovy , Scala и Kotlin наиболее популярными могут быть . Примечательной особенностью языков JVM является то, что они совместимы друг с другом , так что, например, библиотеки Scala можно использовать с программами Java и наоборот. [ 8 ]
Java 7 JVM реализует JSR 292: поддержка динамически типизированных языков [ 9 ] на платформе Java — новая функция, поддерживающая динамически типизированные языки в JVM. Эта функция разработана в рамках проекта Da Vinci Machine , цель которого — расширить JVM, чтобы она поддерживала другие языки, кроме Java. [ 10 ] [ 11 ]
Верификатор байт-кода
[ редактировать ]Основная философия Java заключается в том, что она по своей сути безопасна с точки зрения того, что ни одна пользовательская программа не может привести к сбою хост-машины или иным образом ненадлежащим образом вмешаться в другие операции на хост-машине, и что можно защитить определенные методы и структуры данных, принадлежащие доверенным лицам. код от доступа или повреждения ненадежным кодом, выполняющимся в той же JVM. Кроме того, не допускается возникновение распространенных ошибок программиста, которые часто приводят к повреждению данных или непредсказуемому поведению, например, к доступу к концу массива или использованию неинициализированного указателя. Эту безопасность обеспечивают несколько функций Java, в том числе модель классов, куча со сбором мусора и верификатор.
JVM проверяет весь байт-код перед его выполнением. Эта проверка состоит в основном из трех типов проверок:
- Филиалы всегда находятся в действительных местах.
- Данные всегда инициализируются, а ссылки всегда типобезопасны.
- Доступ к частным или пакетным частным данным и методам жестко контролируется.
Первые две из этих проверок происходят в основном на этапе проверки, который происходит, когда класс загружается и становится пригодным для использования. Третий в основном выполняется динамически, когда к элементам данных или методам класса впервые обращается другой класс.
Верификатор допускает только некоторые последовательности байт-кода в допустимых программах, например, инструкция перехода (ветви) может быть нацелена только на инструкцию внутри того же метода . Более того, верификатор гарантирует, что любая данная инструкция работает в фиксированном месте стека. [ 12 ] позволяя JIT-компилятору преобразовывать доступ к стеку в доступ к фиксированному регистру. По этой причине тот факт, что JVM представляет собой стековую архитектуру, не подразумевает снижения скорости эмуляции на регистровых архитектурах при использовании JIT-компилятора. В условиях архитектуры JVM с верификацией кода для JIT-компилятора не имеет значения, получает ли он именованные мнимые регистры или воображаемые позиции стека, которые должны быть выделены регистрам целевой архитектуры. Фактически, проверка кода отличает JVM от классической стековой архитектуры, эффективная эмуляция которой с помощью JIT-компилятора более сложна и обычно выполняется более медленным интерпретатором. Кроме того, интерпретатор, используемый JVM по умолчанию, представляет собой специальный тип, известный как интерпретатор шаблонов, который преобразует байт-код непосредственно в собственный машинный язык на основе регистров, а не эмулирует стек, как типичный интерпретатор. [ 13 ] Во многих аспектах интерпретатор HotSpot можно считать JIT-компилятором, а не настоящим интерпретатором, то есть архитектура стека, на которую нацелен байт-код, на самом деле не используется в реализации, а является просто спецификацией промежуточного представления, которое вполне может быть реализовано в регистре. основанная архитектура. Другим примером архитектуры стека, являющейся просто спецификацией и реализованной в виртуальной машине на основе регистров, является Common Language Runtime . [ 14 ]
В исходной спецификации средства проверки байт-кода использовался естественный язык, который в некоторых отношениях был неполным или неверным. Был предпринят ряд попыток определить JVM как формальную систему. Благодаря этому можно более тщательно проанализировать безопасность текущих реализаций JVM и предотвратить потенциальные уязвимости безопасности. Также можно будет оптимизировать JVM, пропустив ненужные проверки безопасности, если безопасность запускаемого приложения будет доказана. [ 15 ]
Безопасное выполнение удаленного кода
[ редактировать ]Архитектура виртуальной машины обеспечивает очень детальный контроль над действиями, которые разрешено выполнять коду внутри машины. Он предполагает, что код «семантически» корректен, то есть он успешно прошел (формальный) процесс проверки байт-кода, материализуемый инструментом, возможно, вне виртуальной машины. Это сделано для обеспечения безопасного выполнения ненадежного кода из удаленных источников, модели, используемой Java-апплетами , и других безопасных загрузок кода. После проверки байт-кода загруженный код запускается в ограниченной « песочнице », которая предназначена для защиты пользователя от неправильного поведения или вредоносного кода. В дополнение к процессу проверки байт-кода издатели могут приобрести сертификат, с помощью которого можно будет ставить цифровую подпись апплетам как безопасным, что дает им разрешение просить пользователя выйти из «песочницы» и получить доступ к локальной файловой системе, буферу обмена , запускать внешние части программного обеспечения. , или сеть.
Формальное доказательство верификаторов байт-кода было выполнено индустрией Javacard (формальная разработка встроенного верификатора для байт-кода Java Card). [ 16 ] )
Интерпретатор байт-кода и JIT-компилятор
[ редактировать ]Для каждой аппаратной архитектуры байт-кода Java свой интерпретатор необходим . Если на компьютере есть интерпретатор байт-кода Java, он может запускать любую программу байт-кода Java, и одну и ту же программу можно запускать на любом компьютере, имеющем такой интерпретатор.
Когда байт-код Java выполняется интерпретатором, выполнение всегда будет медленнее, чем выполнение той же программы, скомпилированной на родном машинном языке. Эту проблему смягчают JIT-компиляторы для выполнения байт-кода Java. JIT-компилятор может транслировать байт-код Java на собственный машинный язык во время выполнения программы. Переведенные части программы могут выполняться гораздо быстрее, чем интерпретироваться. Этот метод применяется к часто выполняемым частям программы. Таким образом, JIT-компилятор может значительно ускорить общее время выполнения.
Между языком программирования Java и байт-кодом Java нет необходимой связи. Программа, написанная на Java, может быть скомпилирована непосредственно в машинный язык реального компьютера, а программы, написанные на других языках, кроме Java, могут быть скомпилированы в байт-код Java.
Байт-код Java должен быть независимым от платформы и безопасным. [ 17 ] Некоторые реализации JVM не включают интерпретатор, а состоят только из JIT-компилятора. [ 18 ]
JVM в веб-браузере
[ редактировать ]В начале существования платформы Java JVM позиционировалась как веб-технология для создания насыщенных веб-приложений . По состоянию на 2018 год [update]Большинство веб-браузеров и операционных систем, входящих в состав веб-браузеров, не поставляются с подключаемым модулем Java и не допускают неопубликованную загрузку каких-либо отличных от Flash подключаемых модулей, . Плагин браузера Java устарел в JDK 9. [ 19 ]
Плагин браузера Java NPAPI был разработан , чтобы позволить JVM выполнять так называемые Java-апплеты, встроенные в HTML-страницы. В браузерах с установленным плагином апплету разрешено рисовать в прямоугольной области назначенной ему страницы. Поскольку плагин включает в себя JVM, Java-апплеты не ограничиваются языком программирования Java; любой язык, предназначенный для JVM, может работать в плагине. Ограниченный набор API позволяет апплетам получать доступ к микрофону пользователя или 3D-ускорению, хотя апплеты не могут изменять страницу за пределами ее прямоугольной области. Adobe Flash Player , основная конкурирующая технология, в этом отношении работает таким же образом.
По состоянию на июнь 2015 г. [update] По данным W3Techs, использование Java-апплетов и Silverlight упало до 0,1% для всех веб-сайтов, а использование Flash упало до 10,8%. [ 20 ]
JVM и интерпретаторы JavaScript
[ редактировать ]С мая 2016 года JavaPoly позволяет пользователям импортировать неизмененные библиотеки Java и вызывать их непосредственно из JavaScript. JavaPoly позволяет веб-сайтам использовать неизмененные библиотеки Java, даже если на компьютере пользователя не установлена Java. [ 21 ]
Транспиляция в JavaScript
[ редактировать ]В связи с постоянным улучшением скорости выполнения JavaScript в сочетании с увеличением использования мобильных устройств, веб-браузеры которых не поддерживают плагины, предпринимаются усилия по таргетированию этих пользователей путем транспиляции в JavaScript. Можно перенести исходный код или байт-код JVM в JavaScript.
Компиляция байт-кода JVM, универсального для всех языков JVM, позволяет использовать существующий компилятор языка для создания байт-кода. Основным байт-кодом JVM для транспиляторов JavaScript является TeaVM, [ 22 ] компилятор, содержащийся в Dragome Web SDK, [ 23 ] Bck2Brush, [ 24 ] и j2js-компилятор. [ 25 ]
К ведущим транспиляторам из языков JVM в JavaScript относятся транспилятор Java-to-JavaScript, содержащийся в Google Web Toolkit , Clojurescript (Clojure), GrooScript (Apache Groovy), Scala.js (Scala) и других. [ 26 ]
См. также
[ редактировать ]- Общеязыковая среда выполнения
- Список виртуальных машин Java
- Список языков JVM
- Сравнение виртуальных машин Java
- Сравнение программного обеспечения для виртуализации приложений
- Автоматическая обработка исключений
- Производительность Java
- Java-процессор
- Виртуальная машина К (KVM)
Ссылки
[ редактировать ]- ^ Ян (24 июня 2023 г.). «Примечания к выпуску JDK 20» . Корпорация Оракл . Архивировано из оригинала 9 июля 2021 г. Проверено 24 июня 2023 г.
- ^ Билл Веннерс, Внутри виртуальной машины Java. Архивировано 25 января 2021 г. в Wayback Machine, глава 5.
- ^ «Программа Java Community Process (SM) — JSR: запросы спецификаций Java — подробно JSR № 924» . Jcp.org. Архивировано из оригинала 24 декабря 2020 г. Проверено 26 июня 2015 г.
- ^ «Программа Java Community Process (SM) — JSR: запросы спецификаций Java — подробно JSR № 202» . Jcp.org. Архивировано из оригинала 26 февраля 2012 г. Проверено 26 июня 2015 г.
- ^ Спецификация виртуальной машины Java, заархивированная 9 июля 2008 г. на Wayback Machine ( первая версия , заархивированная 12 октября 2008 г. на Wayback Machine , и вторая , заархивированная 25 сентября 2011 г. на Wayback Machine, также доступны в Интернете).
- ^ «Глава 2. Структура виртуальной машины Java» . Архивировано из оригинала 15 сентября 2021 г. Проверено 15 сентября 2021 г.
- ^ «Спецификация виртуальной машины Java: Java SE 7 Edition» (PDF) . Документы.oracle.com. Архивировано (PDF) из оригинала 04 февраля 2021 г. Проверено 26 июня 2015 г.
- ^ «Часто задаваемые вопросы — совместимость Java» . scala-lang.org . Архивировано из оригинала 9 августа 2020 г. Проверено 18 ноября 2015 г.
- ^ «Программа Java Community Process (SM) — JSR: запросы спецификаций Java — подробно JSR № 292» . Jcp.org. Архивировано из оригинала 20 декабря 2020 г. Проверено 26 июня 2015 г.
- ^ «Проект «Машина Да Винчи»» . Openjdk.java.net. Архивировано из оригинала 11 ноября 2020 г. Проверено 26 июня 2015 г.
- ^ «Новая функция JDK 7: поддержка динамически типизированных языков в виртуальной машине Java» . Oracle.com. Архивировано из оригинала 13 сентября 2018 г. Проверено 26 июня 2015 г.
- ^ «Процесс проверки» . Спецификация виртуальной машины Java . Сан Микросистемс. 1999. Архивировано из оригинала 21 марта 2011 г. Проверено 31 мая 2009 г.
- ^ «Обзор среды выполнения HotSpot — интерпретатор» . OpenJDK . Архивировано из оригинала 21 мая 2022 г. Проверено 24 мая 2021 г.
- ^ «Почему бы не сделать CLR основанным на регистрах? · Проблема № 4775 · dotnet/runtime» . Гитхаб . Архивировано из оригинала 20 апреля 2023 г. Проверено 24 мая 2021 г.
- ^ Фройнд, Стивен Н.; Митчелл, Джон К. (1999). «Формальная структура языка и верификатора байт-кода Java». Материалы 14-й конференции ACM SIGPLAN по объектно-ориентированному программированию, системам, языкам и приложениям — OOPSLA '99 . стр. 147–166. CiteSeerX 10.1.1.2.4663 . дои : 10.1145/320384.320397 . ISBN 978-1581132380 . S2CID 14302964 .
- ^ Кассет, Людовик; Берди, Лилиан; Реке, Антуан (10 апреля 2002 г.). «Формальная разработка встроенного средства проверки байт-кода карты Java» (PDF) . Инрия — Национальный институт исследований в области цифровой науки и технологий при Университете Лазурного Берега . Архивировано (PDF) из оригинала 3 октября 2022 года.
- ^ Дэвид Дж. Эк, Введение в программирование с использованием Java. Архивировано 11 октября 2014 г. на Wayback Machine , седьмое издание, версия 7.0, август 2014 г., раздел 1.3 «Виртуальная машина Java».
- ^ Введение в Oracle JRockit. Архивировано 6 сентября 2015 г. в выпуске Wayback Machine R28, часть 2. «Понимание своевременной компиляции и оптимизации».
- ^ «Oracle объявляет устаревшим плагин Java для браузера и готовится к его прекращению» . Арс Техника . 28 января 2016 года. Архивировано из оригинала 8 апреля 2016 года . Проверено 15 апреля 2016 г.
- ^ «Исторические ежегодные тенденции использования клиентских языков программирования, июнь 2015 г.» . W3techs.com . Проверено 26 июня 2015 г.
- ^ Криль, Пол (13 мая 2016 г.). «JavaPoly.js импортирует существующий код Java и вызывает его непосредственно из JavaScript» . Инфомир . Архивировано из оригинала 25 июля 2016 года . Проверено 18 июля 2016 г.
- ^ «Домашняя страница проекта TeaVM» . Teavm.org. Архивировано из оригинала 27 июня 2015 г. Проверено 26 июня 2015 г.
- ^ «Dragome Web SDK» . Dragome.com. Архивировано из оригинала 1 августа 2015 г. Проверено 26 июня 2015 г.
- ^ «Bck2Brwsr — APIDesign» . Wiki.apidesign.org. Архивировано из оригинала 27 июня 2015 г. Проверено 26 июня 2015 г.
- ^ Вольфганг Кюн (декатур). j2js-компилятор. Архивировано 29 сентября 2013 г. на сайте Wayback Machine GitHub.
- ^ «Список языков, которые компилируются в JS · jashkenas/coffeescript Wiki · GitHub» . Гитхаб.com. 19.06.2015. Архивировано из оригинала 31 января 2020 г. Проверено 26 июня 2015 г.
- Разъяснения и поправки к спецификации виртуальной машины Java, второе издание, заархивированное 10 января 2006 г. на Wayback Machine, включает список изменений, которые необходимо внести для поддержки J2SE 5.0 и JSR 45.
- JSR 45, заархивированный 5 февраля 2006 г. на Wayback Machine , определяет изменения в формате файла класса для поддержки отладки на уровне исходного кода таких языков, как JavaServer Pages (JSP) и SQLJ , которые переведены на Java.