What Is JVM Option “-XX:-OmitStackTraceInFastThrow” ?

TLDR

  • JVM stops outputting stack trace of the exception which often occurs for performance purpose.
  • By adding “-XX:-OmitStackTraceInFastThrow”, we can disable that optimization.

What is “-XX:-OmitStackTraceInFastThrow”

The “OmitStackTraceInFastThrow” was first introduced in JDK5. According to the release note of JDK5, the compiler in the server VM stops outputting the stack trace of the exceptions which have been thrown a few times. This is a one of optimizations which happens in C2 compile. And by adding “-XX:-OmitStackTraceInFastThrow”, we can disable this optimization.

According to the source code of OpenJDK, this optimization is applied to following exceptions

  • NullPointerException
  • ArithmeticException
  • ArrayIndexOutOfBoundsException
  • ArrayStoreException
  • ClassCastException

Try It Out

My runtime is …

java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

The code is …

public class TestOmitStackTraceInFastThrow {

    public static void main(String[] args) {
        int counter = 0;
        while(true) {
            try {
                Object obj = null;
                /*
                 * If we cause the exception every time(= without this "if" statement), the optimization does not happen somehow.
                 * So, cause it conditionally.
                 */
                if(counter % 2 == 0) {
                    obj = new Object();
                }
                // Cause NullpointerException
                obj.getClass();
            }catch(NullPointerException e) {
                e.printStackTrace();
            }
            counter++;
        }
    }
}

I confirmed that the stack trace of NullPointerException disappeared by executing this code after a while without that JVM option. And by adding it, the stack trace never disappeared.

With other codes, I also confirmed that the stack trace of an exception out of that optimization (i.e. IllegalArgumentException) never disappeared.

Should We Use the Flag?

To make it easy to debug, I think we should use the the flag in local environment and staging environment. In production environment, I think basically we should use the flag. Of course if exceptions are thrown a lot of times and tons of stack trace are logged, the performance can be compromised. However, in that case, there is something wrong with the system and the clue for the problem is needed. So, if the application is not supposed to throw exceptions very often, we should use this flag even in production environment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s