jvm 抛出Java异常时是否生成堆栈跟踪?

1szpjjfi  于 2022-11-07  发布在  Java
关注(0)|答案(6)|浏览(138)

这是假设我们不调用.printstacktrace方法--只是抛出和捕获。
我们正在考虑这样做以解决某些性能瓶颈。

nle07wnf

nle07wnf1#

不,堆栈跟踪是在构造异常对象时生成的,而不是在抛出异常对象时生成的。Throwable()构造函数调用fillInStackTrace()。(至少在Sun/Oracle的JDK 6 for Windows中是这样的。)

unguejic

unguejic2#

构造异常时捕获堆栈跟踪。
如果您真的不关心stacktrace,您可以构造一个异常并多次抛出它,但这看起来像是一个黑客,可能会令人困惑。

6ju8rftf

6ju8rftf3#

Throwable对象捕获当前堆栈(使用本地代码),不管它是否被打印。这就是为什么Exceptions不应该(ab)用于控制流的原因。

a1o7rhls

a1o7rhls4#

当调用printStackTrace()方法时,它不会延迟生成
Neal Gaft(构建Java团队的前Sun工程师)提到了异常性能here
到目前为止,异常处理中开销最大的部分是在创建异常时捕获堆栈跟踪
另请参阅this question

7hiiyaii

7hiiyaii5#

正如上面所回答的,堆栈跟踪不是在抛出异常时生成的。相反,它们是在构造异常时生成的。我已经在下面测试过了。在我看来,这并不直观。错误发生的地方是抛出异常的地方,而不是构造异常的地方。

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);
    }
}

输出为:

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)

请注意堆栈跟踪如何提到maininstantiateException,而不是test1

vtwuwzda

vtwuwzda6#

FYI。你可以重载fillInStackTrace来避免性能损失。我们在twitter上这样做的时候,我们需要一些我们不关心堆栈跟踪的异常。
Play框架也在Play 1.3.x行中执行此操作。
此外,您可以中断点fillInStackTrace,以查看它是否在建构时完成。

相关问题