open-jdk中的本机方法fillInStackTrace调用 JVM_FillInStackTrace(env,throwable)是否未提供此方法的源?
throw是一个jvm指令 athrow 。类似于组装跳跃的东西 Jvm本身就是本机代码,因此在jvm中实现的任何东西都是原生的。那么抛出原生代码? 换句话说,对fillInStackTrace的内在调用不会产生通常的JNI调用的成本吗?(并且成本是填充堆栈跟踪)
缓存异常的try-catch是否可以保证正常工作?如何填充异常表。对于同样的异常,我会有多个匹配的catch块?
在网络应用程序(或任何具有类似延迟的应用程序)中,它们真的很贵吗? 假设一个web服务get / employee / {invalid_id}抛出 javax.ws.rs NotFoundException而不是使用if / else返回404响应。 考虑到http请求,响应和对象-Json序列化/反序列化的成本,异常的成本并不多。
答案 0 :(得分:1)
创建异常对象时,需要捕获堆栈跟踪。 JVM通过遍历java堆栈来查找调用链中导致此点的所有方法。
调用方法时,fillInStackTrace方法的成本与java堆栈的深度成比例。与此成本相比,JNI与内在开销相比较低。
异常捕获与使用缓存的异常或新创建的异常无关。执行 athrow 字节码时,JVM遍历java堆栈并查找可以使catch块能够处理当前异常类型的方法。
例外情况适用于特殊事件,不应用于控制流程。
答案 1 :(得分:0)
在实践中,异常 用于非本地控制流。例如,jruby和scala(以及可能的其他基于JVM的语言)使用它们来打破功能循环体或从闭包中返回外部函数。
但是他们使用的是优化的,不会填充堆栈跟踪和/或使用预先分配的异常,如果它可以内联它们,JVM会优化为goto。但这些都是没有其他选择的特殊情况。
在一般情况下,例外情况仅应用于表示异常行为 例外仍然可以意味着预期但不常见在可以被视为慢速代码路径的情况下,异常恢复是如此昂贵,无论如何生成异常相比之下的价格可以忽略不计。各种与网络相关的例外情况就是一个例子,因为网络永远不会100%可靠,但错误也不会占据大部分业务。