There are different levels of JIT, as you've noticed (including not running the JIT at all).
In older versions of Java, you used to have to select them at first (e.g. -Xint
, -client
, -server
) to run with just interpreter, with just the client (C1) compiler, or just the server (C2) compiler.
Tiered compilation, which came in with Java 7, meant that the hotspot compiler could shift between those steps seamlessly. So what happens is that after a certain amount of runs, the code will be compiled with C1, and then after more runs, it will be compiled with C2. This is on a method-by-method basis, so when an app is running a significant portion will just be running under interpreter (which is for cold code) and then after code is run a lot (hot) then it will be compiled to be more performant. You can see the different levels by running
$ 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)
The -XX:-TieredCompilation
is essentially TieredCompilation=false
which means don't do this transition, and you have to select up front whether to use the client or server compiler. The JVM heuristically decides which mode to apply based on your CPU; if you have multiple processors or a 64-bit VM then it will use a Server VM (C2), otherwise it will use a Client VM (C1).
So -Xint
will run with just the interpreter (i.e. no compiler) and you can select either only C1 or C2 with -client
or -server
respectively, along with the -XX:-TieredCompilation
-XX:-TieredCompilation
now (1.) disable C1 and always compile to the max (C2) or (2.) lead the JVM to heuristically decide which compilation tiers to disable based on the CPU (as stated by @AlBlue)? It also makes it hard for me to decide, which to accept as correct answer :P – Truckle