stringtranslate.com

Байт-код Java

Байт-код Java — это набор инструкций виртуальной машины Java (JVM), который имеет решающее значение для выполнения программ, написанных на языке Java и других JVM-совместимых языках. [1] Каждая операция с байт-кодом в JVM представлена ​​одним байтом, отсюда и название « байт-код », что делает ее компактной формой инструкции. [2] Эта промежуточная форма позволяет программам Java быть независимыми от платформы, поскольку они компилируются не в собственный машинный код, а в универсальный исполняемый формат в различных реализациях JVM.

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

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

Отношение к Java

Java- программисту вообще не обязательно знать или понимать байт-код Java. Однако, как говорится в журнале IBM DeveloperWorks: «Понимание байт-кода и того, какой байт-код может быть сгенерирован компилятором Java, помогает программисту Java так же, как знание ассемблера помогает программисту C или C++ ». [4]

Архитектура набора команд

JVM является одновременно стековой машиной и регистровой машиной . Каждый кадр вызова метода имеет «стек операндов» и массив «локальных переменных». [5] : 2.6  Стек операндов используется для операндов вычислений и для получения возвращаемого значения вызываемого метода, в то время как локальные переменные служат той же цели, что и регистры , а также используются для передачи аргументов метода. Максимальный размер стека операндов и массива локальных переменных, вычисленный компилятором, является частью атрибутов каждого метода. [5] : 4.7.3  Каждый из них может иметь независимый размер от 0 до 65535 значений, где каждое значение составляет 32 бита. longи doubleтипы, которые имеют размер 64 бита, занимают две последовательные локальные переменные [5] : 2.6.1  (которые не обязательно должны быть выровнены по 64 битам в массиве локальных переменных) или одно значение в стеке операндов (но считаются как две единицы в глубине стека). [5] : 2.6.2 

Набор инструкций

Каждый байт-код состоит из одного байта, представляющего код операции , а также нуля или более байтов для операндов. [5] : 2,11 

Из 256 возможных опкодов длиной в байт по состоянию на 2015 год 202 используются (~79%), 51 зарезервированы для использования в будущем (~20%), а 3 инструкции (~1%) постоянно зарезервированы для реализаций JVM для использовать. [5] : 6.2  Два из них ( impdep1и impdep2) предназначены для создания ловушек для программного и аппаратного обеспечения, специфичного для реализации, соответственно. Третий используется отладчиками для реализации точек останова.

Инструкции делятся на несколько широких групп:

Есть также несколько инструкций для ряда более специализированных задач, таких как выдача исключений, синхронизация и т. д.

Многие инструкции имеют префиксы и/или суффиксы, относящиеся к типам операндов, с которыми они работают. [5] : 2.11.1  К ним относятся следующие:

Например, iaddдобавится два целых числа и daddдва двойных числа. Инструкции const, load, и storeтакже могут иметь суффикс вида , где n — число от 0 до 3 для и . Максимальное n для зависит от типа._nloadstoreconst

Инструкции constпомещают значение указанного типа в стек. Например, iconst_5в стек будет помещено целое число (32-битное значение) со значением 5, а в стек dconst_1будет помещено двойное значение (64-битное значение с плавающей запятой) со значением 1. Существует также aconst_null, который отправляет nullссылку. n для инструкций и указывает индекс в массиве локальных переменных, из которого выполняется загрузка или сохранение . Инструкция помещает объект из локальной переменной 0 в стек (обычно это объект ). сохраняет целое число на вершине стека в локальную переменную 1. Для локальных переменных после 3 суффикс отбрасывается и необходимо использовать операнды.loadstoreaload_0thisistore_1

Пример

Рассмотрим следующий код Java:

внешний : for ( int i = 2 ; я < 1000 ; я ++ ) { for ( int j = 2 ; j < i ; j ++ ) { if ( i % j == 0 ) продолжить внешний ; } Система . вне . печатьln ( я ); }                              

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

0 : iconst_2 1 : istore_1 2 : iload_1 3 : sipush 1000 6 : if_icmpge 44 9 : iconst_2 10 : istore_2 11 : iload_2 12 : iload_1 13 : if_icmpge 31 16 : iload_1 17 : iload_2 18 : irem 19 : если не 25 22 : перейти к 38 25 : iinc 2, 1 28 : перейти к 11 31 : getstatic #84; // Поле java/lang/System.out : Ljava/io/PrintStream; 34 : iload_1 35 : вызвать виртуальный #85 ; // Метод java/io/PrintStream.println:(I)V 38 : iinc 1, 1 41 : переход к 2 44 : возврат                                       

Поколение

Наиболее распространенным языком, предназначенным для виртуальной машины Java для создания байт-кода Java, является Java. Первоначально существовал только один компилятор — компилятор javac от Sun Microsystems , который компилирует исходный код Java в байт-код Java; но поскольку все спецификации байт-кода Java теперь доступны, другие стороны предоставили компиляторы, которые создают байт-код Java. Примеры других компиляторов включают:

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

Другие разработали компиляторы для разных языков программирования для виртуальной машины Java, например:

Исполнение

Сегодня доступно несколько виртуальных машин Java для выполнения байт-кода Java, как бесплатных, так и коммерческих продуктов. Если выполнение байт-кода на виртуальной машине нежелательно, разработчик может также скомпилировать исходный код Java или байт-код непосредственно в машинный код с помощью таких инструментов, как компилятор GNU для Java (GCJ). Некоторые процессоры могут самостоятельно выполнять байт-код Java. Такие процессоры называются процессорами Java .

Поддержка динамических языков

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

В JSR 292 ( Поддержка динамически типизированных языков на платформе Java ) [13] добавлена ​​новая invokedynamicинструкция на уровне JVM, позволяющая вызывать метод на основе динамической проверки типов (вместо существующей invokevirtualинструкции со статической проверкой типов). Da Vinci Machine — это прототип реализации виртуальной машины, на котором размещены расширения JVM, предназначенные для поддержки динамических языков. Все JVM, поддерживающие JSE 7, также включают invokedynamicкод операции.

Смотрите также

Рекомендации

  1. ^ ab «Спецификация виртуальной машины Java». Оракул . Проверено 14 ноября 2023 г.
  2. ^ Аб Линдхольм, Тим (2015). Спецификация виртуальной машины Java . Оракул. ISBN 978-0133905908.
  3. ^ Арнольд, Кен (1996). «Язык программирования Java». Сан Микросистемс . 1 (1): 30–40.
  4. ^ «Разработчик IBM». разработчик.ibm.com . Проверено 20 февраля 2006 г.
  5. ^ abcdefg Линдхольм, Тим; Йеллин, Фрэнк; Браха, Гилад; Бакли, Алекс (13 февраля 2015 г.). Спецификация виртуальной машины Java (Java SE 8-е изд.).
  6. ^ Домашняя страница Жасмин
  7. ^ Ямайка: ассемблер макросов виртуальной машины Java (JVM).
  8. ^ Домашняя страница Кракатау
  9. ^ Домашняя страница Сирени
  10. ^ Примечания к выпуску Free Pascal 3.0
  11. ^ Бесплатная цель JVM Pascal
  12. Наттер, Чарльз (3 января 2007 г.). «InvokeDynamic: действительно полезно?» . Проверено 25 января 2008 г.
  13. ^ см. JSR 292

Внешние ссылки