Виртуальная машина Java

Виртуальная машина JavaВ предыдущей статье «Язык программирования Java» мы поговорили о зарождении и становлении языка Java, а в этой статье мы поговорим о виртуальной машине Java. Язык Java является скомпилированным и интерпретированным языком. Исходный код Java превращен в простые бинарные инструкции, что больше похоже на машинный код микропроцессора. Как бы то ни было, если источник С или С++ уменьшен до родных инструкций для определенной модели или процессора, то код Java скомпилирован в универсальный формат — инструкции для виртуальной машины.

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

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

Читать также:  Основные операции ввода/вывода в C++

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

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

Среда выполнения Java
Среда выполнения Java

Исторически, интерпретаторы считались медленными, но Java не является традиционным интерпретированным языком. В дополнение к компиляции исходного кода в портативный байт-код Java была тщательно разработана таким образом, что программная реализация системы выполнения может далее оптимизировать свою производительность, компилируя байт-код в оригинальный машинный код на лету. Это называется компиляция «точно в срок», или динамическая компиляция. С динамической компиляцией код Java может выполняться так же быстро, как оригинальный код, и поддерживать свою транспортабельность и безопасность.

Читать также:  Лямбда-выражения на C++ с примерами

Этот пункт часто непонятен тем, кто хочет сравнить производительность языков. Существует только одна серьезная проблема, от которой страдает компилируемый Java-код во время выполнения ради безопасности и архитектуры виртуальной машины, проверка границ массива. Все остальное может быть оптимизировано в оригинальный код так же, как при статической компиляции языка. Кроме этого, язык Java содержит больше структурной информации, чем многие другие языки, предусматривая больше типов оптимизации. Также помните, что эти оптимизации могут осуществляться во время выполнения, принимая во внимание реальное поведение и характеристики приложений. Что может быть сделано во время компиляции, чего нельзя сделать лучше во время выполнения? Что ж, кое-чем приходиться поступиться: временем.

Проблема традиционной динамической компиляции — это то, что оптимизация кода занимает время. Итак, динамический компилятор может давать достойные результаты, но может страдать от значительного времени ожидания при запуске приложения. В основном это не имеет большого значения для долго работающих приложений серверной стороны, но является серьезной проблемой для программного обеспечения клиентской стороны и приложении, которые работают на меньших устройствах с ограниченными возможностями. Чтобы решить этот вопрос, технология компилирования Java, называемая HotSpot, использует прием, именуемый адаптивной компиляцией. Если вы посмотрите, на что в действительности расходуется время работы программ, окажется, что они тратят почти все время, выполняя относительно небольшую часть кода снова и снова. Участок кода, который повторно выполняется, может быть только малым фрагментом всей программы, но его поведение определяет общую производительность программы. Адаптивная компиляция также позволяет времени выполнения Java использовать преимущества новых типов оптимизации, которая не может быть выполнена в статически компилируемых языках, отсюда утверждение, что Java-код работает быстрее, чем С/С++ в некоторых случаях.

Читать также:  Константы в С++

Чтобы получить преимущество от этого факта, технология HotSpot начинает как обычный интерпретатор байт-кода Java, но с одной разницей: она измеряет (профилирует) код во время его выполнения, чтобы увидеть, какие части кода выполняются многократно. Когда она знает, какие части кода являются критическими для производительности , технология HotSpot компилирует эти части в оптимальный собственный машинный код. Поскольку она компилирует только маленькую часть программы в машинный код, она имеет возможность использовать время, необходимое для оптимизации этих частей. Остальная часть программы может вообще не нуждаться в компиляции — только интерпретации — что сохраняет память и время. В действительности виртуальная машина Java может работать в двух режимах: клиентском и серверном, что определяет, делать акцент на быстром времени старта и сохранении памяти или на скорости выполнения.

В этом месте возникает естественный вопрос: зачем выбрасывать всю эту хорошую профильную информацию каждый раз, когда выключается приложение? Что ж, компания Sun затронула эту тему во время релиза Java 5.0 через использование общих классов и классов только для чтения, которые перманентно хранятся в оптимизированной форме. Это значительно уменьшило и время запуска, и наложение многих javа-приложений на одной машине. Эта технология довольно сложная, но идея простая: оптимизировать части программы, которые должны работать быстро, и не беспокоиться обо всем остальном.

В следующей статье мы с вами сравним язык программирования Java с другими языками программирования.

С Уважением, МониторБанк

Добавить комментарий