В спецификации JVM нет ничего, что предписывало бы какую-либо конкретную стратегию выполнения. Некоторые JVM только интерпретируют, у них даже нет компилятора. Некоторые JVM только JIT компилируются, у них даже нет интерпретатора. Некоторые JVM имеют и как интерпретатор и компилятор (или даже несколько компиляторов) и статически выбирают между ними при запуске. Некоторые из них и динамически переключаются назад и вперед во время выполнения. Некоторые даже не являются виртуальными машинами в обычном смысле слова на всех , они просто статически компилируют байт-код JVM в собственный машинный код заранее.
У конкретной JVM, о которой вы спрашиваете, Oracle HotSpot JVM, есть один интерпретатор и два компилятора, называемые компиляторами C1 и C2, также известные как клиент и сервер компиляторы после соответствующих им параметров командной строки. HotSpot динамически переключается между интерпретатором и одним из компиляторов во время выполнения (но он не будет переключаться между двумя компиляторами, вы должны указать один из них в командной строке, а затем только тот, который будет использоваться для все время работы JVM) .
Согласно документу здесь Начиная с некоторых более поздних выпусков Java SE 7, стала доступна новая функция под названием многоуровневая компиляция. Эта функция использует режим компилятора C1 в начале, чтобы обеспечить лучшую производительность при запуске. После правильного прогрева приложения режим компилятора C2 вступает во владение, чтобы обеспечить более агрессивные оптимизации и, как правило, лучшую производительность
Компилятор C1 - это оптимизирующий компилятор, который работает довольно быстро и не использует много памяти. Компилятор C2 намного агрессивнее оптимизирует, но также медленнее и использует больше памяти.
Вы выбираете между этими двумя параметрами, указав параметры командной строки -client
и -server
(-client
- значение по умолчанию, если вы не указали один), которое также устанавливает пару других параметров JVM, таких как порог JIT по умолчанию (в режиме -client
методы будут скомпилированы после того, как они были интерпретированы 1500 раз, в режиме -server
после 10000 раз, можно задать с помощью аргумента командной строки -XX:CompileThreshold
).
Будет ли «большинство пользователей настольных компьютеров» работать в режиме компиляции или интерпретации, во многом зависит от того, какой код они выполняют. Я предполагаю, что подавляющее большинство пользователей настольных компьютеров используют JSM HotSpot из Oracle JRE / JDK или одного из его форков (например, SoyLatte в OSX, IcedTea или OpenJDK в Unix / BSD / Linux) и не используют параметры командной строки. поэтому они, вероятно, получат компилятор C1 с пороговым значением 1500 JIT по умолчанию. (Но приложения, такие как IntelliJ, Eclipse или NetBeans, имеют свои собственные сценарии запуска, которые обычно предоставляют различные аргументы командной строки.)
В моем случае, например, я часто запускаю небольшие скрипты, которые никогда не достигают порога JIT, поэтому они никогда не компилируются. (И при этом они не должны быть.)