Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску
Обзор архитектуры виртуальной машины Java (JVM) на основе спецификации виртуальной машины Java Java SE 7 Edition

Java виртуальная машина ( JVM ) представляет собой виртуальную машину , которая позволяет компьютеру работать Java - программ, а также программ , написанных на других языках , которые также составленным в Java байткод . JVM подробно описывается спецификацией, которая формально описывает, что требуется для реализации JVM. Наличие спецификации гарантирует совместимость программ Java в различных реализациях, так что авторам программ, использующим Java Development Kit (JDK), не нужно беспокоиться об особенностях базовой аппаратной платформы.

Эталонная реализация JVM разработана проектом OpenJDK как открытый исходный код и включает JIT-компилятор под названием HotSpot . Коммерчески поддерживаемые выпуски Java, доступные от Oracle Corporation , основаны на среде выполнения OpenJDK. Eclipse OpenJ9 - еще одна JVM с открытым исходным кодом для OpenJDK.

Спецификация JVM [ править ]

Виртуальная машина Java - это абстрактный (виртуальный) компьютер, определенный спецификацией. Используемый алгоритм сборки мусора и какая-либо внутренняя оптимизация инструкций виртуальной машины Java (их перевод в машинный код) не указаны. Основная причина этого упущения состоит в том, чтобы не ограничивать разработчиков без необходимости. Любое приложение Java может быть запущено только внутри некоторой конкретной реализации абстрактной спецификации виртуальной машины Java. [2]

Начиная с Java Platform, Standard Edition (J2SE) 5.0, изменения в спецификации JVM были разработаны в рамках процесса сообщества Java как JSR 924. [3] С 2006 года изменения в спецификации для поддержки изменений, предложенных в формате файла классов (JSR 202) [4] делаются в техническом обслуживании из JSR 924. спецификация для JVM была опубликована в качестве синей книги , [5] предисловия состояний:

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

Одна из JVM Oracle называется HotSpot , другая, унаследованная от BEA Systems, - JRockit . Реализации Java для чистых помещений включают Kaffe , OpenJ9 и CEE-J от Skelmir . Oracle владеет товарным знаком Java и может разрешить его использование для сертификации комплектов реализации как полностью совместимых со спецификацией Oracle.

Загрузчик классов [ править ]

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

Загрузчик классов выполняет три основных действия в этом строгом порядке:

  1. Загрузка: находит и импортирует двоичные данные для типа
  2. Связывание: выполняет проверку, подготовку и (необязательно) разрешение
    • Проверка: обеспечивает правильность импортированного типа
    • Подготовка: выделяет память для переменных класса и инициализирует память значениями по умолчанию
    • Решение: преобразует символьные ссылки из типа в прямые ссылки.
  3. Инициализация: вызывает код Java, который инициализирует переменные класса их правильными начальными значениями.

В общем, существует два типа загрузчика классов: загрузчик классов начальной загрузки и пользовательский загрузчик классов.

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

Архитектура виртуальной машины [ править ]

JVM оперирует примитивными значениями (целыми числами и числами с плавающей запятой) и ссылками . JVM - это, по сути, 32-битная машина. longи doubleтипы, которые являются 64-битными, поддерживаются изначально, но занимают две единицы памяти в локальных переменных кадра или стеке операндов, поскольку каждая единица имеет 32 бита. boolean, byte, short, И charтипы все по знаку ( за исключением того, charчто нулевой расширен ) и работает на 32-битных чисел, так же , как intтипы. У меньших типов есть только несколько специфичных для типа инструкций по загрузке, сохранению и преобразованию типа. booleanработает как 8-битные byteзначения, где 0 представляет, falseа 1 представляетtrue. (Хотя booleanэтот вопрос рассматривался как тип, поскольку спецификация виртуальной машины Java во втором издании прояснила эту проблему, в скомпилированном и исполняемом коде есть небольшая разница между a booleanи a, byteза исключением искажения имени в сигнатурах методов и типа логических массивов. booleanS в сигнатуры методов искажаются, как в Zто время как в то время как bytes искажаются как B. Логические массивы несут тип, boolean[]но используют 8 бит на элемент, а JVM не имеет встроенной возможности упаковывать логические значения в битовый массив , поэтому, за исключением типа, который они выполняют и ведут себя то же, что и byteмассивы. Во всех остальных случаяхbooleanТип фактически неизвестен JVM, поскольку все инструкции для работы с логическими значениями также используются для работы с bytes.)

В JVM есть куча со сборкой мусора для хранения объектов и массивов. Код, константы и другие данные класса хранятся в «области метода». Область метода логически является частью кучи, но реализации могут обрабатывать область метода отдельно от кучи и, например, не могут собирать ее мусором. Каждый поток JVM также имеет свой собственный стек вызовов (для ясности называемый «стеком виртуальной машины Java»), в котором хранятся кадры . Новый фрейм создается каждый раз, когда вызывается метод, и фрейм уничтожается при выходе из этого метода.

Каждый фрейм предоставляет «стек операндов» и массив «локальных переменных». Стек операндов используется для операндов для вычислений и для получения возвращаемого значения вызываемого метода, в то время как локальные переменные служат той же цели, что и регистры, а также используются для передачи аргументов метода. Таким образом, JVM является одновременно стековой и регистровой машиной .

Инструкции по байт-коду [ править ]

В JVM есть инструкции для следующих групп задач:

  • Загрузить и сохранить
  • Арифметика
  • Преобразование типов
  • Создание и манипулирование объектами
  • Управление стеком операндов (push / pop)
  • Передача управления (разветвление)
  • Вызов и возврат метода
  • Выбрасывание исключений
  • Мониторинг параллелизма

Целью является двоичная совместимость. Каждая конкретная операционная система хоста требует собственной реализации JVM и среды выполнения. Эти JVM семантически интерпретируют байт-код одинаково, но фактическая реализация может отличаться. Более сложным, чем просто эмуляция байт-кода, является совместная и эффективная реализация API ядра Java, который должен быть сопоставлен с каждой операционной системой хоста.

Эти инструкции работают с набором общих абстрактные типы данных, а не собственные типы данных любой конкретной архитектуры набора команд .

Языки JVM [ править ]

Язык JVM - это любой язык, функциональность которого может быть выражена в терминах допустимого файла класса, который может быть размещен на виртуальной машине Java. Файл класса содержит инструкции виртуальной машины Java ( байт-код Java ) и таблицу символов, а также другую вспомогательную информацию. Формат файла класса - это независимый от оборудования и операционной системы двоичный формат, используемый для представления скомпилированных классов и интерфейсов. [6]

Существует несколько языков JVM, как старые языки, перенесенные на JVM, так и совершенно новые языки. JRuby и Jython , пожалуй, самые известные порты существующих языков, то есть Ruby и Python соответственно. Из новых языков, которые были созданы с нуля для компиляции в байт-код Java, наиболее популярными могут быть Clojure , Apache Groovy , Scala и Kotlin . Примечательной особенностью языков JVM является то, что они совместимы друг с другом , так что, например, библиотеки Scala могут использоваться с программами Java и наоборот. [7]

Java 7 JVM реализует JSR 292: Поддержка динамически типизированных языков [8] на платформе Java, новую функцию, которая поддерживает динамически типизированные языки в JVM. Эта функция разработана в рамках проекта Da Vinci Machine , задачей которого является расширение JVM для поддержки языков, отличных от Java. [9] [10]

Верификатор байт-кода [ править ]

Базовая философия Java заключается в том, что она по своей сути безопасна с точки зрения того, что никакая пользовательская программа не может привести к сбою хост-машины или иным образом несоответствующим образом вмешиваться в другие операции на хост-машине, и что можно защитить определенные методы и структуры данных, принадлежащие доверенным код от доступа или повреждения ненадежным кодом, выполняемым в той же JVM. Кроме того, недопустимы распространенные ошибки программиста, которые часто приводят к повреждению данных или непредсказуемому поведению, например, доступ к концу массива или использование неинициализированного указателя. Несколько функций Java объединяются для обеспечения этой безопасности, включая модель классов, кучу со сборкой мусора и средство проверки.

JVM проверяет весь байт-код перед его выполнением. Эта проверка состоит в основном из трех типов проверок:

  • Филиалы всегда в действительных местах
  • Данные всегда инициализируются, а ссылки всегда типобезопасны
  • Доступ к приватным или пакетным приватным данным и методам строго контролируется.

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

Верификатор разрешает только некоторые последовательности байт-кода в допустимых программах, например, инструкция перехода (перехода) может нацеливаться только на инструкцию в пределах того же метода . Кроме того, верификатор гарантирует, что любая данная инструкция работает с фиксированным положением стека [11], позволяя JIT-компилятору преобразовывать обращения к стеку в обращения к фиксированным регистрам. Из-за этого то, что JVM представляет собой стековую архитектуру, не подразумевает потери скорости для эмуляции на архитектурах на основе регистров.при использовании JIT-компилятора. Перед лицом архитектуры JVM с проверкой кода для JIT-компилятора не имеет значения, получает ли он именованные мнимые регистры или мнимые позиции стека, которые должны быть выделены регистрам целевой архитектуры. Фактически, проверка кода отличает JVM от классической стековой архитектуры, эффективная эмуляция которой с помощью JIT-компилятора более сложна и обычно выполняется более медленным интерпретатором.

Исходная спецификация для верификатора байт-кода использовала естественный язык, который в некоторых отношениях был неполным или неверным. Было предпринято несколько попыток указать JVM как формальную систему. Таким образом можно более тщательно проанализировать безопасность текущих реализаций JVM и предотвратить возможные взломы. Также можно будет оптимизировать JVM, пропустив ненужные проверки безопасности, если будет доказано, что выполняемое приложение безопасно. [12]

Безопасное выполнение удаленного кода [ править ]

Архитектура виртуальной машины позволяет очень точно контролировать действия, которые разрешено выполнять коду внутри машины. Он предполагает, что код "семантически" правильный, то есть успешно прошел (формальный) процесс проверки байт-кода, материализованный инструментом, возможно, за пределами виртуальной машины. Это разработано для обеспечения безопасного выполнения ненадежного кода из удаленных источников, модели, используемой апплетами Java , и других безопасных загрузок кода. После проверки байт-кода загруженный код запускается в ограниченной « песочнице », которая предназначена для защиты пользователя от неправильного поведения или вредоносного кода. В дополнение к процессу проверки байт-кода издатели могут приобрести сертификат для цифровой подписи.апплеты как безопасные, давая им разрешение попросить пользователя выйти из песочницы и получить доступ к локальной файловой системе, буферу обмена , выполнить внешние части программного обеспечения или сеть.

Формальное подтверждение верификаторов байт-кода было сделано индустрией Javacard (формальная разработка встроенного верификатора для байт-кода карты Java [13] )

Интерпретатор байт-кода и оперативный компилятор [ править ]

Для каждой аппаратной архитектуры требуется свой интерпретатор байт-кода Java . Когда компьютер имеет интерпретатор байт-кода Java, он может запускать любую программу байт-кода Java, и ту же программу можно запускать на любом компьютере, на котором есть такой интерпретатор.

Когда байт-код Java выполняется интерпретатором, выполнение всегда будет медленнее, чем выполнение той же программы, скомпилированной на машинном языке. Эта проблема устраняется JIT-компиляторами для выполнения байт-кода Java. Компилятор JIT может переводить байт-код Java на собственный машинный язык во время выполнения программы. После этого переведенные части программы можно будет выполнить гораздо быстрее, чем их можно будет интерпретировать. Этот метод применяется к тем частям программы, которые часто выполняются. Таким образом, JIT-компилятор может значительно ускорить общее время выполнения.

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

Байт-код Java должен быть независимым от платформы и безопасным. [14] Некоторые реализации JVM не включают интерпретатор, а состоят только из оперативного компилятора. [15]

JVM в веб-браузере [ править ]

В начале существования платформы Java JVM продавалась как веб-технология для создания полнофункциональных веб-приложений . По состоянию на 2018 год большинство веб-браузеров и операционных систем, объединяющих веб-браузеры, не поставляются с подключаемым модулем Java и не разрешают боковую загрузку каких-либо подключаемых модулей, отличных от Flash . Подключаемый модуль браузера Java объявлен устаревшим в JDK 9. [16]

NPAPI Java - браузер плагин был разработан , чтобы позволить JVM для выполнения так называемых Java - апплеты , встроенные в страницы HTML. Для браузеров с установленным подключаемым модулем апплету разрешено рисовать в прямоугольной области на странице, назначенной ему. Поскольку подключаемый модуль включает JVM, апплеты Java не ограничиваются языком программирования Java; любой язык, ориентированный на JVM, может работать в подключаемом модуле. Ограниченный набор API-интерфейсов позволяет апплетам получать доступ к микрофону пользователя или 3D-ускорению, хотя апплеты не могут изменять страницу за пределами ее прямоугольной области. Adobe Flash Player , основная конкурирующая технология, работает в этом отношении точно так же.

По данным W3Techs, по состоянию на июнь 2015 года , использование Java-апплетов и Silverlight упало до 0,1% для всех веб-сайтов, а использование Flash упало до 10,8%. [17]

JVM и интерпретаторы JavaScript [ править ]

С мая 2016 года JavaPoly позволяет пользователям импортировать немодифицированные библиотеки Java и вызывать их непосредственно из JavaScript. JavaPoly позволяет веб-сайтам использовать немодифицированные библиотеки Java, даже если на компьютере пользователя не установлена ​​Java. [18]

Компиляция в JavaScript [ править ]

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

Компиляция байт-кода JVM, который является универсальным для языков JVM, позволяет использовать существующий компилятор языка для создания байт-кода. Основными байт-кодом JVM для компиляторов JavaScript являются TeaVM, [19] компилятор, содержащийся в Dragome Web SDK, [20] Bck2Brwsr, [21] и j2js-compiler. [22]

Ведущие компиляторы с языков JVM на JavaScript включают компилятор Java-to-JavaScript, содержащийся в Google Web Toolkit , Clojurescript ( Clojure ), GrooScript ( Apache Groovy ), Scala.js (Scala) и другие. [23]

Среда выполнения Java [ править ]

Java Runtime Environment (JRE), выпущенная Oracle, представляет собой свободно доступный дистрибутив программного обеспечения, содержащий автономную JVM ( HotSpot ), стандартную библиотеку Java ( Java Class Library ), инструмент конфигурации и - до его прекращения в JDK 9 - плагин для браузера. Это наиболее распространенная среда Java, устанавливаемая на персональных компьютерах в форм-факторе портативного и настольного компьютера . Мобильные телефоны, включая функциональные телефоны, и ранние смартфоны, которые поставляются с JVM, скорее всего, будут включать JVM, предназначенную для запуска приложений, ориентированных на Micro Edition платформы Java. Между тем, большинство современных смартфонов,планшетные компьютеры и другие портативные компьютеры , на которых работают приложения Java, скорее всего, будут делать это благодаря поддержке операционной системы Android , которая включает виртуальную машину с открытым исходным кодом, несовместимую со спецификацией JVM. (Вместо этого инструменты разработки Android от Google принимают программы Java в качестве входных и выходных байт-кода Dalvik , который является собственным форматом ввода для виртуальной машины на устройствах Android.)

Производительность [ править ]

Спецификация JVM дает разработчикам большую свободу действий в отношении деталей реализации. Начиная с Java 1.3, JRE от Oracle содержит JVM под названием HotSpot. Он был разработан как высокопроизводительная JVM.

Чтобы ускорить выполнение кода, HotSpot полагается на своевременную компиляцию. Чтобы ускорить выделение объектов и сборку мусора, HotSpot использует кучу поколений.

Куча поколений [ править ]

Виртуальная машина Java кучей является областью памяти , используемой JVM для динамического выделения памяти . [24]

В HotSpot куча делится на поколения :

  • В молодом поколении хранит недолговечны объекты , которые создаются и сразу же мусор , собранные .
  • Объекты, которые сохраняются дольше, перемещаются в старое поколение (также называемое постоянным поколением ). Эта память разделена на (два) пространства Survivors, где хранятся объекты, которые пережили первую и следующую сборку мусора.

Постоянное поколение (или PermGen ) использовали для класса определений и связанное с ними метаданные до Java 8. Постоянное поколение не было частью кучи. [25] [26] постоянное поколение было удалено из Java 8. [27]

Первоначально не было постоянного поколения, и объекты и классы хранились вместе в одной области. Но поскольку выгрузка классов происходит гораздо реже, чем собираются объекты, перемещение структур классов в определенную область позволило значительно улучшить производительность. [25]

Безопасность [ править ]

Oracle JRE установлен на большом количестве компьютеров. Таким образом, конечные пользователи с устаревшей версией JRE уязвимы для многих известных атак. Это привело к широко распространенному мнению, что Java по своей сути небезопасна. [28] Начиная с Java 1.7, Oracle JRE для Windows включает функцию автоматического обновления.

До прекращения поддержки подключаемого модуля Java-браузера на любой веб-странице потенциально мог быть запущен Java-апплет, который обеспечивал легкодоступную поверхность атаки для вредоносных веб-сайтов. В 2013 году «Лаборатория Касперского» сообщила, что компьютерные преступники предпочитают плагин Java. Эксплойты Java включены во многие пакеты эксплойтов, которые хакеры размещают на взломанных веб-сайтах. [29] Java-апплеты были удалены из Java 11, выпущенного 25 сентября 2018 г.

См. Также [ править ]

  • Список виртуальных машин Java
  • Сравнение виртуальных машин Java
  • Сравнение виртуальных машин приложений
  • Автоматическая обработка исключений
  • Производительность Java
  • Список языков JVM
  • Процессор Java
  • общеязыковая среда выполнения

Ссылки [ править ]

  1. ^ "jdk-updates / jdk15u: tags" . Корпорация Oracle . Проверено 27 января 2021 .
  2. ^ Билл Веннерс, Внутри виртуальной машины Java, Глава 5
  3. ^ "Программа Java Community Process (SM) - JSR: запросы спецификации Java - подробный JSR # 924" . Jcp.org . Проверено 26 июня 2015 .
  4. ^ "Программа Java Community Process (SM) - JSR: запросы спецификации Java - подробный JSR № 202" . Jcp.org . Проверено 26 июня 2015 .
  5. ^ Спецификация виртуальной машины Java ( первая и вторая редакции также доступны в Интернете).
  6. ^ «Спецификация виртуальной машины Java: Java SE 7 Edition» (PDF) . Docs.oracle.com . Проверено 26 июня 2015 .
  7. ^ «Часто задаваемые вопросы - Java Interoperability» . scala-lang.org . Проверено 18 ноября 2015 .
  8. ^ "Программа Java Community Process (SM) - JSR: запросы спецификации Java - деталь JSR # 292" . Jcp.org . Проверено 26 июня 2015 .
  9. ^ "Проект машины Да Винчи" . Openjdk.java.net . Проверено 26 июня 2015 .
  10. ^ «Новая функция JDK 7: поддержка динамически типизированных языков в виртуальной машине Java» . Oracle.com . Проверено 26 июня 2015 .
  11. ^ «Процесс проверки» . Спецификация виртуальной машины Java . Sun Microsystems. 1999 . Проверено 31 мая 2009 .
  12. ^ Freund, Стивен N .; Митчелл, Джон С. (1999). «Формальная основа для языка байт-кода и верификатора Java». Материалы 14-й конференции ACM SIGPLAN по объектно-ориентированному программированию, системам, языкам и приложениям - OOPSLA '99 . С. 147–166. CiteSeerX 10.1.1.2.4663 . DOI : 10.1145 / 320384.320397 . ISBN  978-1581132380.
  13. ^ http://www-sop.inria.fr/everest/Lilian.Burdy/CBR02dsn.pdf
  14. ^ Дэвид Дж. Эк, Введение в программирование с использованием Java , седьмое издание, версия 7.0, август 2014 г., раздел 1.3 «Виртуальная машина Java»
  15. ^ Введение в Oracle JRockit Заархивировано 6 сентября 2015 г. в Wayback Machine Release R28 на 2. «Понимание своевременной компиляции и оптимизации»
  16. ^ «Oracle осуждает плагин для браузера Java, готовится к его прекращению» . Ars Technica . 28 января 2016 . Проверено 15 апреля 2016 года .
  17. ^ «Исторические ежегодные тенденции использования языков программирования на стороне клиента, июнь 2015 г.» . W3techs.com . Проверено 26 июня 2015 .
  18. ^ Криль, Пол (13 мая 2016). «JavaPoly.js импортирует существующий код Java и вызывает его непосредственно из JavaScript» . InfoWorld . Проверено 18 июля +2016 .
  19. ^ "Домашняя страница проекта TeaVM" . Teavm.org . Проверено 26 июня 2015 .
  20. ^ "Dragome Web SDK" . Dragome.com . Проверено 26 июня 2015 .
  21. ^ "Bck2Brwsr - APIDesign" . Wiki.apidesign.org . Проверено 26 июня 2015 .
  22. ^ Вольфганг Куэн (декатур). j2js-компилятор GitHub
  23. ^ «Список языков, компилируемых в JS · jashkenas / coffeescript Wiki · GitHub» . Github.com. 2015-06-19 . Проверено 26 июня 2015 .
  24. ^ «Часто задаваемые вопросы о сборке мусора в виртуальной машине Java Hotspot» . Sun Microsystems . 6 февраля 2003 . Проверено 7 февраля 2009 года .
  25. ^ a b Масамицу, Джон (28 ноября 2006 г.). «Представляя постоянное поколение» . Проверено 7 февраля 2009 года .
  26. Наттер, Чарльз (11 сентября 2008 г.). «Первый вкус InvokeDynamic» . Проверено 7 февраля 2009 года .
  27. ^ «JEP 122: Удалить постоянное поколение» . Корпорация Oracle . 2012-12-04 . Проверено 23 марта 2014 .
  28. ^ «Что такое Java, является ли она небезопасной и стоит ли ее использовать?» . Lifehacker.com. 2013-01-14 . Проверено 26 июня 2015 .
  29. ^ «Есть ли защита от эксплойтов Java? | Лаборатория Касперского» . Kaspersky.com. 2013-09-09. Архивировано из оригинала на 2015-04-04 . Проверено 26 июня 2015 .
  • Разъяснения и поправки к спецификации виртуальной машины Java, второе издание включает список изменений, которые необходимо внести для поддержки J2SE 5.0 и JSR 45.
  • JSR 45 определяет изменения в формате файла класса для поддержки отладки на уровне исходного кода языков, таких как JavaServer Pages (JSP) и SQLJ , которые переведены на Java.

Внешние ссылки [ править ]

  • Спецификация виртуальной машины Java
  • Как скачать и установить готовые пакеты OpenJDK
  • Как установить Java? (JRE от Oracle)