Платформа Java
Компиляция Динамическая компиляция Just-in-time (оперативная) компиляция Динамическая компиляция HotSpot Непрерывная перекомпиляция
Динамическая компиляция Процесс компиляции Java-приложения отличается от процесса компиляции статически компилируемых языков программирования, подобных С или С++. Статический компилятор преобразует исходный код непосредственно в машинные инструкции, которые могут быть выполнены на целевой платформе. Различные аппаратные платформы требуют применения различных компиляторов. Java-компилятор преобразует исходный Java-код в переносимые байт-коды JVM, которые являются для JVM "инструкциями виртуальной машины". В отличие от статических компиляторов javac выполняет очень маленькую оптимизацию - оптимизация, проводимая статическими компиляторами, выполняется во время исполнения программы. Первые поколения JVM были полностью интерпретируемыми. JVM интерпретировала байт-код вместо компиляции его в машинный код и выполнения машинного кода. Этот подход, естественно, не предлагал наилучшей возможной производительности, поскольку система больше времени тратила на выполнение интерпретатора, а не самой программы.
Just-in-time (оперативная) компиляция Интерпретация была хороша для proof-of-concept (доказательство идеи) реализации, но первые JVM сразу обвинили в медлительности. Следующие поколения JVM использовали just-in-time (JIT) компиляторы для ускорения работы. Строго определенная JIT-виртуальная машина перед выполнением преобразовывает все байт-коды в машинный код, но делает это в неторопливом стиле: JIT компилирует code path только тогда, когда знает, что code path будет сейчас выполняться (отсюда и название just-in-time компиляция). Этот подход дает возможность программам стартовать быстрее, поскольку не требуется длительная фаза компиляции перед возможным началом исполнения кода. Использование JIT выглядело многообещающим, но существуют недостатки. JIT-компиляция устранила накладные расходы интерпретации (за счет некоторого дополнительного замедления запуска), но уровень оптимизации кода по некоторым причинам был посредственным. Во избежание значительного замедления при запуске Java-приложений JIT-компилятор должен быть быстрым, т.е. он не может тратить много времени на оптимизацию. И первые JIT-компиляторы были консервативны в создании встроенных предположений, поскольку они не знали, какие классы могут быть загружены позднее. С технической точки зрения JIT-виртуальная машина компилирует каждый байт- код перед его выполнением. Термин JIT часто используется для обозначения любой динамической компиляции байт-кода в машинный код, даже когда возможна интерпретация байт-кода.
Динамическая компиляция HotSpot Исполняющий процесс HotSpot объединяет интерпретацию, профилирование и динамическую компиляцию. Вместо преобразования всех байт-кодов в машинный код HotSpot начинает работу как интерпретатор и компилирует только "горячий" код, то есть код, выполняющийся наиболее часто. Во время выполнения он собирает данные анализа. Эти данные используются для определения фрагментов кода, выполняющихся достаточно часто и заслуживающих компиляции. Компиляция только часто исполняемого кода имеет несколько преимуществ: не тратится время на компиляцию кода, выполняющегося редко, таким образом, компилятор может тратить больше времени на оптимизацию "горячего" кода, поскольку он знает, что время будет потрачено не зря. Кроме того, откладывая компиляцию, компилятор имеет доступ к данным анализа, которые могут быть использованы для улучшения оптимизации, например, встраивать ли вызов конкретного метода. HotSpot поставляется с двумя компиляторами: клиентским и серверным. По умолчанию используется клиентский компилятор. Вы можете выбрать серверный компилятор, указав параметр -server при запуске JVM. Серверный компилятор оптимизирован для повышения пиковой скорости работы и предназначен для "долгоиграющих" серверных приложений. Клиентский компилятор оптимизирован для уменьшения времени начального запуска приложения и занимаемого объема памяти, реализует менее сложную оптимизацию, чем серверный компилятор, и, следовательно, требует меньше времени для компиляции. Серверный компилятор HotSpot может выполнять впечатляющее число видов оптимизации. Среди них множество стандартных видов оптимизации, имеющихся в статических компиляторах, например, выведение кода из тела циклов, общее удаление подвыражения, развертка цикла, удаление проверки диапазона, удаление "мертвого" кода, анализ движения данных, а также множество оптимизаций, обычно не применяющихся в статических компиляторах, например, принудительное встраивание вызовов виртуальных методов.
Непрерывная перекомпиляция Еще одна интересная особенность HotSpot - компиляция не осуществляется по принципу "все или ничего". Code path компилируется в машинный код после интерпретации его определенное количество раз. Но JVM продолжает анализ и может перекомпилировать код заново с более высоким уровнем оптимизации, если решит, что code path является особенно "горячим" или последующий анализ данных показал возможность дополнительной оптимизации. JVM может перекомпилировать одни и те же байт-коды много раз при выполнении одиночного приложения. Для получения более подробной информации о работе компилятора попробуйте вызвать JVM с флагом - XX:+PrintCompilation, который заставляет компилятор (клиентский или серверный) каждый раз во время своей работы выводить на экран короткое сообщение.
Байт-код
Байт-код или – машинно-независимый код низкого уровня, генерируемый транслятором и исполняемый интерпретатором. Большинство инструкций байт-кода эквивалентны одной или нескольким командам ассемблера. Трансляция в байт-код занимает промежуточное положение между компиляцией в машинный код и Байт-код называется так, потому что длина каждого кода операции один байт, но длина кода команды различна. Каждая инструкция представляет собой однобайтовый код операции от 0 до 255, за которым следуют такие параметры, как регистры или адреса памяти. Это в типичном случае, но спецификация байт-кода значительно различается в языке.
Программа на байт-коде обычно выполняется интерпретатором байт- кода, обычно он называется виртуальной машиной Виртуальная машина программная или аппаратная среда, исполняющая некоторый код, или спецификация такой системы
Преимущество – портируемость и безопасность выполнения программ в полной независимости байт-кода от ОС и оборудования. Это позволяет выполнять Java-приложения на любом устройстве, которое поддерживает виртуальную машин гибкая система безопасности благодаря тому, что исполнение программы полностью контролируется виртуальной машиной. Любые операции, которые превышают установленные полномочия программы (например, попытка несанкционированного доступа к данным или соединения с другим компьютером) вызывают немедленное прерывание. Это позволяет пользователям загружать программы, написанные на Java, на их компьютеры (или другие устройства, например, мобильные телефоны) из неизвестных источников, при этом не опасаясь заражения вирусами, пропажи ценной информации исполнение байт-кода виртуальной машиной не снижает производительность программ и алгоритмов, реализованных на языке Java
Языки и среды программирования, использующие байт-код Байткод Java выполняется виртуальной машиной Java Smalltalk Lua Python Виртуальная машина Parrot Платформа Microsoft.NET использует Intermediate Language (IL), исполняемый с помощью Common Language Runtime (CLR). PHP Forth
Объекты создаются с помощью оператора new. Инициализация объек- та производится с помощью соответствующего конструктора. Эти операции разделить нельзя - за new следует конструктор. Пример. Point myPoint = new Point (); Других способов создания объектов (кроме оператора new) язык Java не предоставляет. Объект существует до тех пор, пока на него есть ссылки (то есть пока он прямо или косвенно доступен хотя бы из одной перемен- ной). В языке отсутствуют явные средства удаления объектов. После того, как объект стал недоступен, он оказывается кандида-том для утилизации сборщиком мусора. Объект может стать недоступным, если хранившей его переменной присвоено новое значение или если эта переменная перестала быть доступной (произошел выход из блока). Пример. Point p = new Point (100.0, 100.0);... p = new Point (1.0, 1.0); // На точку с координатами (100, 100) ссылок больше нет { String s = new String ("Local string"); System.out.println (s); } // На строку "Local string" ссылок больше нет В момент утилизации объекта сборщиком мусора будет вызван метод finalize. Из-за того, что сборщик мусора работает в фоновом ре- жиме, вызов finalize является асинхронным.