Overhead associated with Exception vs Throwable in Java
Asked Answered
C

8

27

I know

throw new Exception();

has a pretty large overhead, since it creates a full stackTrace, etc.
Does

throw new Throwable();

present the same problem? Is this behaviour inherited, or does throwing a Throwable has a smaller (o no) overhead?

EDIT
From an analyst point of view, a user inserting wrong password is an exception to the normal execution order of a program. So if I have:

public Session newSession() {  
  validate_user_and_password();   
}

throwing a UserNotValidException would sound correct from an analysts point of view.
Returning null or 0 just sounds incorrect if your code has pretty good abstraction. I just wanted to know if I could actually implement this in code, or if I'd have to just leave it to theory.

There's a good difference between programming-point-of-view exception and analyst-point-of-view exception.

Note: I've given a really simple and silly example, this is not quite my case.
Note 2: I know returning null would be the ordinary thing, but I'm required to have properly abstracted and OO code, and, personally, I see no harm in this.

Christman answered 25/1, 2010 at 1:9 Comment(7)
Why this concern? What's the functional requirement?Ulaulah
You shouldn't be using exceptions in the regular case anyway - they should only be used in exception al circumstances.Lacrimatory
@anon they should be used for "exceptional code paths" which may or may not be as exceptional as one might think. For example, if you avoid filling in the stack trace, it is most performant to use them to signal the end of a stream rather than checking for the end after each read. (This does not apply for looping over arrays though, where the full length is known to the VM.)Pedicel
Think he meant "analyst" as in "business analyst".Ulaulah
I kept reading "annalist" as nihilist.Hamamelidaceous
"annalist" means "historian".Estas
"a user inserting wrong password is an exception to the normal execution order of a program" -- no, it is not remotely exceptional and is in fact the complete opposite. A user entering wrong credentials should be an obvious potential outcome of any authentication process, and your code should expect and handle that case as part of the normal sequence of operations.Embonpoint
A
49

Throwable also creates a stacktrace when it's created. From the java docs for Throwable:

throwable contains a snapshot of the execution stack of its thread at the time it was created.

So in terms of overhead with regards to creating a stacktrace, there should be no difference between Exception and Throwable.

If you are using exceptions for "exceptional events" (as you should be), then you shouldn't be too concerned with the overhead of a stacktrace. An exceptional event occurs rarely in running code. So Exceptions shouldn't impact the performance of normal code in any significant way.

Acarus answered 25/1, 2010 at 1:11 Comment(0)
P
37

Nope, you need your own subclass to avoid that effect.

Exception ex = new Exception() {
    @Override public Throwable fillInStackTrace() {
        return this; // and do nothing else
    }
};

This creates an instance of exception that will not fill the stack trace (the creation of exceptions delegates to fillInStackTrace to actually fill the stack trace) and is thus cheap to create.

Pedicel answered 25/1, 2010 at 1:12 Comment(8)
It seems that return null; will do the same as return this;. Any reason why you would want to use return this;?Beseech
To comply with the API documentation of Throwable.Pedicel
But you're breaking "This method records within this Throwable object information about the current state of the stack frames for the current thread." Edit: But point taken, neat trick!Beseech
HEHEHE, good point ... putting on my lawyer hat: "but it does not say that full information is recorded, so zero information satisfies this requirement" which is even a good argument from an engineering point of view: external clients might rely on not getting a null object but not filling the stack trace just results in an empty array when calling getStackTrace so it is less likely to break code. (Hmm, I should actually verify that last point, I am not even sure, you might get null as well.)Pedicel
In fact, there are Sun-defined exceptions where you won't always get a full stacktrace. For example, StackOverflowError and OutOfMemoryError will not include a full stacktrace in some circumstances.Balmoral
@mangodrunk - the difference between the "violations" is that one (not filling in the stacktrace) is done to achieve a desired effect, and the other (not returning this) is gratuitous and pointless.Balmoral
Scala uses this technique in a ControlFlowException, to implement the break.Convolvulaceous
BTW: forgot to mention I ended up using this implementation to avoid the stacktrace overhead :)Christman
P
3

With JIT compilation, it is actually not still the case that there is a lot of overheard to throwing an Exception in Java. But throwing a Throwable is not much different, since you will get a stack trace there as well.

If you are interested, there is a very interesting paper called "Efficient Java exception handling in just-in-time compilation" (link). Not a light read, but quite informative.

Puett answered 25/1, 2010 at 1:13 Comment(3)
Can you provide a reference for that? I though creating a stack trace is even the more expensive when you got JIT since you have to deoptimize to recover the actual stack trace.Pedicel
IIRC, I measured over 10k cycles from creating an exception. That was a few years ago. It'll presumably be more with full "framework" stack traces.Howlend
The paper is from 2000, isn't that dated by now? I just ask to make sure before reading it :)Pedicel
T
1

You should never be throwing or catching Throwable. The scope of the exception is far too great.

As stated previously, exceptions should be used only where needed, ie: in exceptional circumstances and should be specific to the situation that spawned them. That aside, catching a Throwable implies a host of exceptions, such as OutOfMemoryException. An error of this magnitude can not be recovered from (easily) and should not be handled by the developer.

Tumular answered 25/1, 2010 at 6:12 Comment(3)
I agree, one should never throw new Throwable(), but [at the time of asking my original question], I was considering throw new MyNonStackTracedException() where MyNonStackTracedException extends Throwable (if there was no overhead).Christman
Your advice isn't very good. Telling programmers they shouldn't handle exceptions is a little bit inane. You might at least want to tell your user "hey we're out of memory : (" before you crash your program into the ground.Agustin
You are misinterpreting. The OP asked about throwing Throwable or Exception. If you throw Throwable you need to catch Throwable which has many, many issues related to it.Tumular
P
1

Throwable is parent class of Exception. so Exception class is inherited from Throwable.

Pilaf answered 22/1, 2014 at 13:3 Comment(0)
W
1

Throwable vs. Exception

Java Exception

As @mangoDrunk said:"Throwable is the superclass of exception and error."

Wen answered 12/5, 2015 at 7:31 Comment(1)
Superclass, from what I see on the image included.Christman
A
1

You can look at the source code of the two classes to see that Exception doesn't do anything beyond expose the same constructors as Throwable. All of the meat, and hence overhead, lives in Throwable.

Even if Exception did introduce some additional overhead it would be a clear over-optimization to use Throwable instead. Use the right tool for the job, don't co-opt the wrong tool just because it's lighter.

Avantgarde answered 24/2, 2017 at 1:38 Comment(0)
B
0

java.lang.Exception extends java.lang.Throwable, so it's the same overhead. From the Javadoc:

The Throwable class is the superclass of all errors and exceptions in the Java language. Only objects that are instances of this class (or one of its subclasses) are thrown by the Java Virtual Machine or can be thrown by the Java throw statement. Similarly, only this class or one of its subclasses can be the argument type in a catch clause.

Instances of two subclasses, Error and Exception, are conventionally used to indicate that exceptional situations have occurred. Typically, these instances are freshly created in the context of the exceptional situation so as to include relevant information (such as stack trace data).

Beseech answered 25/1, 2010 at 1:15 Comment(1)
That logic makes no sense - subclasses may introduce much more complexity. Of course in this case it doesn't - but that fact doesn't make your answer any less useless.Agustin

© 2022 - 2024 — McMap. All rights reserved.