提问者:小点点

JVM 何时开始省略堆栈跟踪?


我搜索了很多关于这个话题的内容。但目前还没有具体的解决方案/指南。

从文档中,

在某些情况下,一些虚拟机可能会从堆栈跟踪中省略一个或多个堆栈帧。在极端情况下,不具有有关此可丢弃的堆栈跟踪信息的虚拟机被允许从该方法返回零长度数组。

有人可以阐明这可能/将要发生的条件吗?

我知道,如果一次又一次地生成相同的堆栈跟踪,就会发生这种情况(计数没有硬性规定,AFAIK-否则请更正)。但这难道不是有一个明确的行为吗?

另外,根据这一点,传递-XX:-OmitStackTraceInFastThrow将确保我的StackTrace不会丢失。在生产机器中总是这样做不是明智之举吗?


共1个答案

匿名用户

  • <code>OmitStackTraceInFastThrow</code>是C2编译代码中的一种优化,用于在没有堆栈跟踪的情况下抛出某些隐式异常
  • 优化只适用于隐式异常,即JVM本身抛出的异常,而不是用户代码抛出的异常。这些隐含的例外情况是:<ul>
  • 空指针异常
  • 算术异常
  • 数组索引越界异常
  • 阵列存储异常
  • 类CastException

因此,在 HotSpot JVM 中,如果满足以下所有条件,则异常将没有堆栈跟踪:1) 抛出方法是热的,即由 C2 编译;2)它是一个隐式异常,例如由obj.method()抛出的NPE,而不是抛出新的NullPointerException();3) 至少第二次抛出异常。

优化的目的是消除在快速路径上重复抛出隐式异常时那些(极少数)情况对性能的影响。在我看来,这不是正常情况。异常,尤其是隐式的,通常表示需要修复的错误情况。从这个意义上说,禁用< code >-XX:-omitstacktraceinfaststrow 是可以的。例如,在我们的生产环境中,我们总是禁用它,这节省了我们很多调试时间。然而,我承认,如果存在这样的优化,它有助于解决性能问题。

太长别读Adding-XX:-OmitStackTraceInFastThrow选项确实是个好主意,除非应用程序中的热路径上有许多隐式异常。