What are jvm pre-allocated exceptions?
Asked Answered
F

2

5

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?

Filet answered 8/2, 2017 at 14:5 Comment(3)
Note that preallocated exceptions are not exclusively JVM-allocated exceptions. You can also preallocate and reuse exception instances in pure java, the standard libraries and 3rd-party ones do in fact.Kitchener
@Kitchener would you have a link by any chance?Filet
no links, but I know that jruby uses preallocated exceptions to make non-local controlflow less painful.Kitchener
B
14

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

Beacham answered 8/2, 2017 at 14:41 Comment(0)
C
2

The release notes you posted explain the feature:

Reading the release notes in your post: "The compiler in the server VM now provides correct stack backtraces for all "cold" built-in exceptions. For performance purposes, when such an exception is thrown a few times, the method may be recompiled. After recompilation, the compiler may choose a faster tactic using preallocated exceptions that do not provide a stack trace."

Yes, it is an optimization.

To increase the speed of exception handling, exceptions that are thrown often may be preallocated.

This removes the need to continuously create new exceptions every time one occurs, at the price of loosing stack trace information.

You can remove this feature using the flag -XX:-OmitStackTraceInFastThrow

Cupule answered 8/2, 2017 at 14:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.