Что именно -XX:-TieredCompilation делает?

С помощью java -XX:+PrintFlagsFinal Я нашел TieredCompilation флаг, и я читал об этом немного в Интернете.

Тем не менее, я до сих пор не знаю точно, что происходит при установке его на false,

Я знаю, что система компиляции поддерживает 5 уровней выполнения, в основном разделенных на интерпретатор, C1 и C2:

  • уровень 0 - переводчик
  • уровень 1 - C1 с полной оптимизацией (без профилирования)
  • уровень 2 - C1 с счетчиками вызовов и задников
  • уровень 3 - C1 с полным профилированием (уровень 2 + MDO)
  • уровень 4 - С2

Источник: http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/2b2511bd3cc8/src/share/vm/runtime/advancedThresholdPolicy.hpp#l34

Два вопроса:

(1) путем установки -XX:-TieredCompilation, некоторые из этих уровней просто отключены? Если да, то какой?

(2) Есть ли какой-либо флаг, чтобы решить, следует ли отключить C1 или C2 или вообще не компилировать?

3 ответа

Решение

-XX:-TieredCompilation отключает промежуточные уровни компиляции (1, 2, 3), так что метод либо интерпретируется, либо компилируется на максимальном уровне оптимизации (C2).

Как побочный эффект TieredCompilation Флаг также изменяет количество потоков компилятора, политику компиляции и размер кэша кода по умолчанию. Обратите внимание, что с TieredCompilation отключен

  • будет меньше потоков компилятора;
  • вместо расширенной политики компиляции будет выбрана простая политика компиляции (основанная на вызовах методов и счетчиках задников);
  • размер зарезервированного кеша по умолчанию будет в 5 раз меньше.

Чтобы отключить компилятор C2 и оставить только C1 без дополнительных затрат, установите -XX:TieredStopAtLevel=1,

Чтобы отключить все JIT-компиляторы и запустить все в интерпретаторе, используйте -Xint,

Как вы заметили, существуют разные уровни JIT (в том числе вообще не работает JIT).

В старых версиях Java вам приходилось выбирать их сначала (например, -Xint, -client, -server) работать только с интерпретатором, только с клиентским (C1) компилятором или только с серверным (C2) компилятором.

Многоуровневая компиляция, которая пришла с Java 7, означала, что компилятор горячей точки мог плавно переключаться между этими шагами. Так что получается, что после определенного количества запусков код будет скомпилирован с C1, а затем, после нескольких запусков, скомпилирован с C2. Это основано на методе, поэтому, когда приложение выполняется, значительная часть будет просто работать под интерпретатором (что для холодного кода), а затем после многократного выполнения кода (горячим), то оно будет скомпилировано в быть более производительным. Вы можете увидеть разные уровни, запустив

$ java -XX:+PrintFlagsFinal -version | grep CompileThreshold
intx Tier2CompileThreshold                     = 0
intx Tier3CompileThreshold                     = 2000
intx Tier4CompileThreshold                     = 15000
openjdk version "1.8.0_92"
OpenJDK Runtime Environment (Zulu 8.15.0.1-macosx) (build 1.8.0_92-b15)
OpenJDK 64-Bit Server VM (Zulu 8.15.0.1-macosx) (build 25.92-b15, mixed mode)

-XX:-TieredCompilation по существу TieredCompilation=false что означает не делать этого перехода, и вы должны заранее выбрать, использовать ли клиент или серверный компилятор. JVM эвристически решает, какой режим применять на основе вашего процессора; если у вас несколько процессоров или 64-битная виртуальная машина, она будет использовать серверную виртуальную машину (C2), в противном случае она будет использовать клиентскую виртуальную машину (C1).

Так -Xint будет работать только с интерпретатором (то есть без компилятора), и вы можете выбрать только C1 или C2 с -client или же -server соответственно вместе с -XX:-TieredCompilation

Как пользователь Java 8, рекомендуется отключить TieredComplilation для производственного использования с плавающей запятой.

Oracle не решит эту проблему на Java8. Все точки доступа JVM 8 с G1GC имеют одинаковую проблему.

( Bug1) ( Bug2)

Другие вопросы по тегам