This kind of compilation is called on-stack replacement (OSR), because even if the loop is
compiled, that isn't sufficient: the JVM has to have the ability to start executing the compiled
version of the loop while the loop is still running. When the code for the loop has finished
compiling, the JVM replaces the code (on-stack), and the next iteration of the loop will ex-
ecute the much-faster compiled version of the code.
Standard compilation is triggered by the value of the -XX:CompileThreshold= N flag. The
default value of N for the client compiler is 1,500; for the server compiler it is 10,000.
Changing the value of the CompileThreshold flag will cause the the compiler to choose to
compile the code sooner (or later) than it normally would have. Note, however, that although
there is one flag here, the threshold is calculated by adding the sum of the back-edge loop
counter plus the method entry counter.
CHANGING OSR COMPILATION
It is very rare to change the threshold for OSR compilation: in fact, though OSR compilation is
frequently triggered in benchmarks (and particularly in microbenchmarks), it is triggered less fre-
quently in application code.
To provide complete details, OSR compilation is triggered by the value of three flags:
OSR trigger = (CompileThreshold *
((OnStackReplacePercentage - InterpreterProfilePercentage)/100))
In all compilers, the default value of the -XX:InterpreterProfilePercentage= N flag is 33. In
the client compiler, the default value of the -XX:OnStackReplacePercentage= N flag is 933, and
so the client compiler requires that the back-edge counter hit 13,500 before it will begin OSR
compilation. In the server compiler, OSR compilation begins when the back-edge counter hits
10,700, since the default value for OnStackReplacePercentage is 140. Note that for tiered com-
pilation, these decisions are based on different flags altogether, though the concepts are the same;
full details are given in Advanced Compiler Tunings .
Changing the CompileThreshold flag has been a popular recommendation in performance
circles for quite some time; in fact, you may have seen that Java benchmarks often use this
flag (e.g., frequently after 8,000 iterations for the server compiler).
We've seen that there is a big difference between the ultimate performance of the client and
server compilers, due largely to the information available to the compiler when it compiles a