14

This is assuming we don't call the .printstacktrace method - just throwing and catching.

We are considering this for some performance bottlenecks.

Something else
  • 211
  • 2
  • 7
  • 4
    If you want preformance, you really shouldn't be throwing an exception, that should only be for exceptional cases which don't impact your performance. Perhaps you can do what your attempting without an exception? – Peter Lawrey Nov 16 '10 at 15:02

6 Answers6

19

No, stack traces are generated when exception object is constructed, not when it's thrown. The Throwable() constructors call fillInStackTrace(). (At least in Sun/Oracle's JDK 6 for Windows.)

ctomek
  • 1,696
  • 16
  • 35
perp
  • 3,883
  • 4
  • 31
  • 29
9

Stacktrace is captured when exception is constructed.

If you really don't care about stacktrace, you can construct an exception once and throw it multiple times, but it looks like a hack and can be confusing.

axtavt
  • 239,438
  • 41
  • 511
  • 482
4

A Throwable object captures the current stack (using native code) if it will be printed or not. That's the reason why Exceptions shouldn't be (ab)used for control flow.

stacker
  • 68,052
  • 28
  • 140
  • 210
4

it is not built lazily when the printStackTrace() method is called

Neal Gafter (former Sun engineer on the team that builds Java) mentioned exception performance here:

The most expensive part of exception handling by far is capturing the stack trace when creating the exception

Also, see this question.

Community
  • 1
  • 1
Brad Cupit
  • 6,530
  • 8
  • 55
  • 60
  • Exceptions cost a lot because each time an exception is thrown, the stack trace must be created and populated. Imagine a balance transfer operation which fails in 1% of cases due to lack of funds. Even with this relatively little rate of failures, performance may be severely impacted. See source code and benchmark results here: http://www.jquantlib.org/index.php/Cost_of_Exceptions_in_Java – Richard Gomes Feb 08 '11 at 03:51
2

As answered above, stack traces are NOT generated when an exception is thrown. Rather, they are generated when the exception is constructed. I've tested it below. In my opinion this is not intuitive. The place where something wrong happens is the place where the exception is thrown, not where it's constructed.

class ExceptionNewVsThrow {

    private static RuntimeException instantiateException() {
        return new RuntimeException("Hello");
    }

    private static void test1(Exception exception) throws Exception {
        throw exception;
    }
    
    public static void main(String[] args) throws Exception {
        Exception exception = instantiateException();
        test1(exception);
    }
}

And the output is:

Exception in thread "main" java.lang.RuntimeException: Hello
    at FSystem.experimental.exceptions.ExceptionNewVsThrow.instantiateException(ExceptionNewVsThrow.java:18)
    at FSystem.experimental.exceptions.ExceptionNewVsThrow.main(ExceptionNewVsThrow.java:26)

Notice how the stack trace mentions main and instantiateException, but not test1

claude
  • 99
  • 8
0

FYI. You can overload fillInStackTrace to avoid the performance penalty. We do this at twitter when we want for certain exceptions where we do not care about a stack trace.

play framework also does this in play 1.3.x line.

Also, you can breakpoint fillInStackTrace to see it is done at construction.

Dean Hiller
  • 19,235
  • 25
  • 129
  • 212