Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are jvm pre-allocated exceptions?

I see references to pre-allocated JVM exceptions there: - http://www.oracle.com/technetwork/java/javase/relnotes-139183.html - http://dev.clojure.org/display/community/Project+Ideas+2016

But looking for that I see only information about missing stacktraces. What are JVM allocated exceptions? It seems like an optimisation.

How does it work, and what are it's trade-offs?

like image 698
nha Avatar asked Feb 08 '17 14:02

nha


1 Answers

These are exceptions which are preallocated on the start of JVM. Preallocated exceptions should be implicit: they are thrown by JVM, not by throw new ... when unexpected condition occurs: dereferencing null pointer, accessing array with negative index etc.

When method starts to throw (implicitly) one of these exceptions too frequently, JVM will notice that and replace allocation of exception on every throw with throwing already preallocated exception without stacktrace.

This mechanism is implementation dependent, so if we're talking about hotspot you can find the list of these exceptions in graphKit.cpp:

NullPointerException 
ArithmeticException
ArrayIndexOutOfBoundsException
ArrayStoreException
ClassCastException

The rationale is pretty simple: the most expensive part of throwing an exception is not an actual throwing and stack unwinding, but creating stacktrace in exception (it's a relatively slow call to the VM and happens in exception constructor via Throwable#fillInStackTrace). To find concrete numbers and relative cost you can read awesome article by hotspot performance engineer about exceptional performance.

Some people use exceptions for regular control flow (please don't do that) or for performance sake (which is usually incorrect, for example see this kinda popular connection pool framework), so hotspot makes this [probably bad] code a little bit faster via throwing already created exception without stacktrace (so the most expensive part of throwing is eliminated).

Downside of this approach is that now you have stacktraceless exceptions. It's not a big deal: if these implicit exceptions are thrown that frequently, you probably don't use their stacktraces. But if this assumption is incorrect you will have exceptions without traces in your logs. To prevent this you can use -XX:-OmitStackTraceInFastThrow

like image 56
qwwdfsad Avatar answered Sep 20 '22 04:09

qwwdfsad