16

I've searched much on the topic. But no concrete solution/guide is present.

From the docs,

Some virtual machines may, under some circumstances, omit one or more stack frames from the stack trace. In the extreme case, a virtual machine that has no stack trace information concerning this throwable is permitted to return a zero-length array from this method.

Can someone shed light on what conditions this may/will happen?

I know it happens if the same stack trace is produced over and over again (There is no hard-and-fast-rule on the count, AFAIK- Correct me otherwise). But must not this be having a defined behaviour?

Also,As per this, passing -XX:-OmitStackTraceInFastThrow will make sure my StackTrace is not lost. Isn't it wise always to do that in Production machines?

Mohamed Anees A
  • 4,119
  • 1
  • 22
  • 35
  • 1
    Performance. Will happen if it's been generating the same stack trace over and over. – Michael Nov 04 '19 at 15:09
  • Re: the extreme case. I think if the JVM is generating an out of memory error, for example, it may not even have enough memory to construct the stack trace, so it has to be empty. – Michael Nov 04 '19 at 15:15
  • If the memory consumption is that critical, it is better off to throw OOM than "silently" suppressing the stack trace, right? – Mohamed Anees A Nov 04 '19 at 15:19
  • 2
    "*Isn't it wise always to do that in Production machines?*" No. Our prod machines have this feature enabled. We care about the performance gain more than we care about getting the full stack trace every time. If it is being omitted, it means that it's been generated already. To get the full stack trace, just go to the first occurrence in your logs. – Michael Nov 04 '19 at 15:21
  • I don't know what you mean. OOM exception is always thrown. It's just whether the OOM that is thrown includes the stack trace or not. If there is no memory to generate it, there is no option but to throw it without. – Michael Nov 04 '19 at 15:24
  • the classical case is something like `for (int i = 0; i < 100_000; i++) {try {throwsNPE();} catch (NullPointerException e) {}}; throwsNPE();`. If you ever run into something like this, you should already have more than enough stack traces. – Johannes Kuhn Nov 04 '19 at 15:44

1 Answers1

27
  1. OmitStackTraceInFastThrow is an optimization in C2 compiled code to throw certain implicit exceptions without stack traces.
  2. The optimization applies only to implicit exceptions, i.e. exceptions thrown by JVM itself, not by user code. These implicit exceptions are:
    • NullPointerException
    • ArithmeticException
    • ArrayIndexOutOfBoundsException
    • ArrayStoreException
    • ClassCastException
  3. Stack traces are omitted, only if JVM knows the exception has happened earlier at this particular place.

So, in HotSpot JVM an exception won't have a stack trace, if all of the following conditions are met: 1) a throwing method is hot, i.e. compiled by C2; 2) it is an implicit exception, e.g. NPE thrown by obj.method(), but not by throw new NullPointerException(); 3) an exception is thrown at least for the second time.

The purpose of the optimization is to eliminate performance impact of those (arguably rare) cases when an implicit exception is repeatedly thrown on the fast path. In my opinion, this isn't a normal situation. Exceptions, especially implicit, typically denote an error condition which needs to be fixed. In this sense, it's OK to disable -XX:-OmitStackTraceInFastThrow. E.g. in our production environment we always disable it, and it saved us much debugging time. However, I admit that if such an optimization exists, there were cases where it helped to solve performance issues.

TL;DR Adding -XX:-OmitStackTraceInFastThrow option can be indeed a good idea, unless there are many implicit exceptions on a hot path in your application.

apangin
  • 92,924
  • 10
  • 193
  • 247
  • 4
    besides the fast-throw feature, there are other circumstances, [like insufficient memory](https://stackoverflow.com/a/46298757/2711488) which could lead to throwables without stack traces. – Holger Nov 05 '19 at 10:45