为了账号安全,请及时绑定邮箱和手机立即绑定

JVM什么时候开始省略堆栈跟踪?

JVM什么时候开始省略堆栈跟踪?

繁花如伊 2024-01-28 20:30:07
我已经对这个主题进行了很多搜索。但没有具体的解决方案/指南。从文档中,在某些情况下,某些虚拟机可能会从堆栈跟踪中省略一个或多个堆栈帧。在极端情况下,没有与此 throwable 相关的堆栈跟踪信息的虚拟机可以从此方法返回零长度数组。有人可以阐明这可能/将会发生的条件吗?我知道如果一遍又一遍地生成相同的堆栈跟踪,就会发生这种情况(计数上没有硬性规则,据我所知-否则请纠正我)。但这难道不应该有一个明确的行为吗?另外,根据这一点,通过-XX:-OmitStackTraceInFastThrow将确保我的StackTrace不会丢失。在生产机器中这样做不是明智之举吗?
查看完整描述

1 回答

?
千巷猫影

TA贡献1829条经验 获得超7个赞

  1. OmitStackTraceInFastThrow是C2 编译代码中的优化,可抛出某些隐式异常,而无需堆栈跟踪。

  2. 该优化仅适用于隐式异常,即 JVM 本身引发的异常,而不是用户代码引发的异常。这些隐式异常是:

    • 空指针异常

    • 算术异常

    • ArrayIndexOutOfBoundsException

    • 数组存储异常

    • 类转换异常

  3. 仅当 JVM 知道该特定位置较早发生异常时,才会忽略堆栈跟踪。

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

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

TL;DR添加-XX:-OmitStackTraceInFastThrow选项确实是一个好主意,除非应用程序中的热路径上存在许多隐式异常。


查看完整回答
反对 回复 2024-01-28
  • 1 回答
  • 0 关注
  • 30 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信