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

Can Hotspot JIT optimizations for fast throw exceptions lead to ambiguous results?

This question 处理 JIT 编译器确定它不再生成堆栈跟踪的情况,如果它认为它以前已经这样做了一定次数的话。我知道这被称为 "fast throw" 或 "preallocated" 异常。

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

我的问题是,是否可以保证从报告的预分配异常的发生映射回至少一个较早异常的实例是确定性的,如果不是,是否有任何方法可以避免这是一个来源使用 -XX:-OmitStackTraceInFastThrow.

完全禁用优化的歧义

一个简单的例子:

报告的 shortened/preallocated 异常是一些通用的异常,例如 NullPointerException。 如果在 JVM 的早期生命周期中只有一种类型的堆栈跟踪以 NPE 结束,那么没有问题。但是,如果代码中的不同点已经存在不止一个 NPE 怎么办? JVM 没有给出任何指示,或者是否已经编译出任何早期堆栈,那么您如何确定性地确定堆栈跟踪本来应该是什么?

这种情况真的会发生吗,或者现代热点 JIT 是否足够聪明,可以避免产生这种歧义?

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

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