快速抛出异常的热点 JIT 优化会导致不明确的结果吗?

mag*_*can 4 java jvm-hotspot

这个问题涉及 JIT 编译器确定它不会再生成堆栈跟踪的情况,如果它认为它之前已经这样做了一定次数。我知道这被称为“快速抛出”或“预分配”异常。

一般来说,如果遇到这样一个预先分配的异常,在 JIT 认为值得编译之前,在 JVM 生命周期的某个更早的时间点应该至少可以找到一次丢失的堆栈跟踪。

我的问题是,从报告的预分配异常到至少一个早期异常实例的映射是否可以保证是确定性的,如果不是,是否有任何方法可以避免这是除禁用之外的歧义来源完全使用 -XX:-OmitStackTraceInFastThrow 进行优化。

一个简单的例子:

报告的缩短/预分配异常是通用的,例如 NullPointerException。如果在 JVM 的早期生命周期中只有一种类型的堆栈跟踪以 NPE 结束,那么没问题。但是,如果代码中的各个点已经有多个 NPE 呢?JVM 没有给出任何早期堆栈已被编译或是否已被编译的任何指示,那么您如何确定性地确定堆栈跟踪会是什么?

这种情况真的会出现吗,或者现代 Hotspot JIT 是否足够聪明来避免产生这种歧义?

Gil*_* D. 5

JVM 本身不会尝试将这些预先分配的异常映射到任何先前抛出的异常。作为开发人员,您可以尝试猜测这些预分配异常的来源,但无法保证。

如果您正在尝试调试某些内容并看到无堆栈跟踪的异常,最安全的做法是-XX:-OmitStackTraceInFastThrow在尝试查找问题根源时禁用优化。