Method inlining in Java

Ludvig Westerdahl
CodeX
Published in
3 min readAug 17, 2021

--

Method inlining example.

This article aims to introduce method inlining and demonstrate the effects.

TL;DR
Method inlining is enabled by default and should not be disabled. It is a compiler optimization that essentially replaces a method call by its content.

Let’s talk a little about compiler optimizations in Java. The HotSpot JVM just-in-time (JIT) compiler can perform a plethora of optimizations such as but not limited to;

  • When to use a register over main memory to store values.
  • Skipping method lookups.
  • Escape analysis (-XX:+DoEscapeAnalysis, -XX:-DoEscapeAnalysis)
  • Inlining (-XX:+Inline, -XX:-Inline)

Method inlining

It is activated/disabled using the following flag (activated by default). Most java true/false flags use this syntax of -XX:[+,-]FLAG to set to true or false [1].

-XX:+Inline (enables)
-XX:-Inline (disables)

Inlining is an optimization where the compiler has determined that a method is not needed and has replaced the method call with simple statements. The compiler basically performs the same optimization as I have done manually in the example below.

“Manual” method inlining

In the early versions of Java, performing this manual inlining used to be a common way to achieve better performance. Obviously we shouldn’t do that anymore as the compiler handles it for us.

So, how big of an improvement can this yield? I have constructed an extreme example to demonstrate the effects, see below.

Method inlining test code.

The code basically performs a lot of getting and setting, mostly setting values to the Point (note the loop inside Point#setX and Point#setY).

Inlining enabled

If we run the example without any argument (-XX:+Inline is enabled by default), we can see that the execution time is close to 0.

> javac MethodInlining.java> java MethodInliningRunning pid: 41301
Elapsed time (ms): 0
Point[x=49995000, y=49995000]

Inlining disabled

Let’s compare it with disabling inlining.

> javac MethodInlining.java> java -XX:-Inline MethodInliningRunning pid: 41303
Elapsed time (ms): 9754
Point[x=49995000, y=49995000]

The test now took close to 10 seconds (!). Here we have an extreme case where method invocation overhead takes up most of the time. Obviously you won’t see this in the wild, however, you might see a performance reduction of somewhere between 30–50% if inlining is disabled [2].

Logging inlining in the JVM

There are some flags you can use in order to get some insight into the JVM and when it inlines methods.

> javac MethodInlining.java> java -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining MethodInlining...
@ 22 MethodInlining$Point::setX (19 bytes) inline (hot)
@ 9 MethodInlining$Point::setXInside (6 bytes) accessor
...
@ 32 MethodInlining$Point::setY (19 bytes) inline (hot)
@ 9 MethodInlining$Point::setYInside (6 bytes) accessor
...

This tells you that the compiler has inlined the method. Running the example without inlining we can note the difference.

> javac MethodInlining.java> java -XX:-Inline -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining MethodInlining...
@ 9 MethodInlining$Point::setXInside (6 bytes) not inlineable
@ 9 MethodInlining$Point::setYInside (6 bytes) not inlineable
...

Finally, when do methods get inlined? Well, it depends on how hot the method is (how often it is called) and it’s size. If a method is determined hot and eligible for inlining it will be inlined if it is smaller than the flag below (in bytes).

> java -XX:+PrintFlagsFinal -version | grep FreqInlineSizeintx FreqInlineSize = 325 {pd product} {default}openjdk version "13.0.2" 2020-01-14
OpenJDK Runtime Environment (build 13.0.2+8)
OpenJDK 64-Bit Server VM (build 13.0.2+8, mixed mode, sharing)

Alternatively, it is eligible for inlining only if it is smaller than the flag below (in bytes).

> java -XX:+PrintFlagsFinal -version | grep MaxInlineSizeintx MaxInlineSize = 35 {product} {default}openjdk version "13.0.2" 2020-01-14
OpenJDK Runtime Environment (build 13.0.2+8)
OpenJDK 64-Bit Server VM (build 13.0.2+8, mixed mode, sharing)

References

[1] Java HotSpot VM Options
https://www.oracle.com/java/technologies/javase/vmoptions-jsp.html

[2] Java Performance — The Definitive Guide by Scott Oaks

--

--

Ludvig Westerdahl
CodeX

I'm a software engineer with a great passion for both software and finance. Hit me up at: https://linkedin.com/in/ludvigwesterdahl