Подтвердить что ты не робот

Как байт-код проверяется в JVM?

Как байт-код проверяется в JVM?

4b9b3361

Ответ 1

У самих Oracle есть небольшая фрагментарная страница о том, как она работает здесь.

В принципе, JRE не доверяет JDK. Это потому, что он не знает, какой компилятор JDK создал файл класса. Он обрабатывает файл класса как враждебный, пока не будет проверен.

Расширяясь на этом, проверка байт-кода является необходимым шагом для защиты от того, что Sun вызывает "враждебный компилятор". Собственный Java-компилятор Sun гарантирует, что исходный код Java не нарушает правила безопасности, но когда приложение импортирует фрагмент кода, на самом деле он не знает, следуют ли коды кода правилам языка Java для обеспечения безопасности. Другими словами, код, возможно, не был создан надежным компилятором Java.

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

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

Ниже приведена ссылка на связанную диаграмму:

                    <<<=== Unsafe / Safe ===>>>
                                  \
+---------------+        +-------------------+
|  Java source  |   +--> |   Class loader    | --+
+---------------+   |    | Bytecode verifier |   |
        |           |    +-------------------+   |
        V           |             /              |
+---------------+   |             \              V
| Java compiler |  Network        /    +-------------------+
+---------------+   |             \    |      JVM/JIT      |
        |           |             /    +-------------------+
        V           |             \              |
+---------------+   |             /              V
| Java bytecode | --+             \    +-------------------+
+---------------+                 /    | Operating system  |
                                  \    +-------------------+
                                  /              |
                                  \              V
                                  /    +-------------------+
                                  \    |     Hardware      |
                                  /    +-------------------+
                                  \
                    <<<=== Unsafe / Safe ===>>>

Ответ 2

Лучшим источником информации, вероятно, является соответствующий раздел спецификации JVM, 4.10 Проверка файлов классов.

Подробнее см. ссылку, но в целом:

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

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

Верификатор также выполняет проверку, которая может быть выполнена без просмотра массива кода атрибута Code (§4.7.3). Выполненные проверки включают следующее:

  • Обеспечение того, чтобы конечные классы не были подклассифицированы и что окончательные методы не переопределены (§5.4.5).
  • Проверка того, что каждый класс (кроме Object) имеет прямой суперкласс.
  • Обеспечение того, что постоянный пул удовлетворяет документированным статическим ограничениям; например, что каждая структура CONSTANT_Class_info в пуле констант содержит в своем элементе name_index допустимый индекс пула констант для структуры CONSTANT_Utf8_info.
  • Проверка того, что все ссылки на поля и ссылки на методы в пуле констант имеют допустимые имена, допустимые классы и допустимый дескриптор типа.