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.