Магия Java: байт-код

Основная особенность, которая позволяет языку Java решать обе описанные проблемы обеспечения безопасности и переносимости программ состоит в том, что вывод компилятора Java не является исполняемым кодом. Скорее он представляет собой так называемый байт-код. Байт-код — это в высшей степени оптимизированный набор инструкций, предназначенных для исполнения системой времени выполнения Java, называемой виртуальной машиной Java (Java Virtual Machine — JVM). Собственно говоря, первоначальная версия JVM разрабатывалась в качестве интерпретатора байт-кода. Это может вызывать определенное удивление, поскольку по соображениям обеспечения максимальной производительности многие современные языки призваны создавать исполняемый код.

Однако то, что Java-программа интерпретируется машиной JVM, помогает решать основные проблемы, связанные с программами, предназначенными для Web. И вот почему.

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

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

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

Хотя язык Java был задуман в качестве интерпретируемого языка, ничто не препятствует Java выполнять компиляцию байт кода во внутренний код "на лету" для повышения производительности. Поэтому вскоре после появления Java компания Sun начала поставлять свою технологию HotSpot. Эта технология предоставляет оперативный (Justin-Time — JIT) компилятор байт-кода. Когда JIT-компилятор является составной частью машины JVM, избранные фрагменты байт-кода один за другим компилируются в исполняемый код в реальном времени, по соответствующим запросам. Важно понимать, что одновременная компиляция всей Java-программы в исполняемый код нецелесообразна, поскольку Java выполняет различные проверки, которые могут быть осуществлены только во время выполнения. Вместо этого во время выполнения JIT-компилятор компилирует код по мере необходимости. Более того, компилируются не все фрагменты байт-кода, а только те, которым компиляция принесет выгоду. Остальной код просто интерпретируется. Однако JIT-подход все же обеспечивает значительное повышение производительности. Даже в случае применения к байт-коду динамической компиляции, характеристики переносимости и безопасности сохраняются, поскольку машина JVM по-прежнему отвечает за целостность среды выполнения.