Из Википедии, бесплатной энциклопедии
  (Перенаправлено с виртуальной машины Java )
Перейти к навигации Перейти к поиску
Обзор архитектуры виртуальной машины 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 Card [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)