Home United States USA — software Why Does the JIT Continually Recompile the Same Method?

Why Does the JIT Continually Recompile the Same Method?

168
0
SHARE

We know that the Java JIT compiler compiles and recompiles methods based on usage statistics. As a method gets called repeatedly, interpretation moves to …
Join the DZone community and get the full member experience. A Stack Overflow user noticed frequent recompilations, even after a substantial JVM uptime, and couldn’t find an explanation based on the common knowledge on JIT compilers. We know that the Java JIT compiler compiles and recompiles methods based on usage statistics. As a method gets called repeatedly, interpretation moves to JIT compilation. More frequent calls can trigger recompilation with a higher optimization level. Despite of that theoretically simple optimization chain, the actual compilation invocations visualized with -XX:+PrintCompilation can look like they’re not following that strategy at all. The output was as follows: Even after a substantial JVM uptime (the first column represents the uptime in ms), recompilations of the same method were triggered. At first sight, That doesn’t seem to correspond to the optimization chain outlined above. The short answer for the impatient: JIT deoptimization causes compiled code to be disabled (‘made not entrant’), freed (‘made zombie’), and recompiled if called again (a sufficient number of times). The JVM method cache maintains four states: A method can be in_use, it might have been disabled by deoptimization ( not_entrant) but can still be called, or it can be marked as a zombie if it’s non_entrant and not in use anymore. Lastly, the method can be marked for unloading. In the case of tiered compilation, the initial compilation result produced by the client compiler (C1) might be replaced with a compilation result from the server compiler (C2) depending on usage statistics. The compilation level in the -XX:+PrintCompilation output ranges from 0 to 4.0 represents interpretation,1 to 3 represents different optimization levels of the client compiler,4 represents the server compiler. In the user’s output, you can see java.lang. String.equals() transitioning from 3 to 4. When that happens, the original method is marked as not_entrant.

Continue reading...