20

我一直在阅读 JLS,遇到了第11.1.3 节。我引用的异步异常:

大多数异常是同步发生的,因为它们发生在线程中,并且在程序中被指定为可能导致此类异常的某个点处发生。相比之下,异步异常是可能在程序执行的任何时候发生的异常。

异步异常仅由于以下原因而发生:

[...]

  • Java 虚拟机中的内部错误或资源限制,阻止它实现 Java 编程语言的语义。在这种情况下,抛出的异步异常是 VirtualMachineError 子类的一个实例。

是否有可能捕获此类异常以用于日志记录或通知(因为我相信这样的事情是不可恢复的)?我怎样才能做到这一点?

4

2 回答 2

19

您可以像任何其他异常一样捕获此类异常。唯一的问题是它们可能出现在程序中的任何地方,因此很难可靠地捕获它们。您基本上必须将run所有线程的方法和main方法包装在一个try..catch块中,但是对于您无法控制的线程(如 Swing EDT 或计时器线程等),您不能这样做。

通常也不建议捕获 的任何子类Error,因为 JVM 可能处于不稳定状态,这可能会导致进一步的故障(例如,在 的情况下OutOfMemoryError,您甚至可能没有足够的内存来处理异常)。Error但是,日志记录将是在我眼中捕捉 s 的正当理由。

我建议的解决方案是为此使用未捕获的异常处理程序,方法是将其设置为默认异常处理程序。在此处理程序中,您将获得所有异常和错误,如果它们没有在代码中的任何地方捕获,您可以尝试记录它们。

于 2012-11-22T06:39:55.480 回答
3

捕获这些异常(VirtualMachineError 的子类)没有意义,因为您没有不知道 pogram 处于何种状态,文档说虚拟机错误:

当内部错误或资源限制阻止它实现本章中描述的语义时,Java 虚拟机实现会抛出一个对象,该对象是类 VirtualMethodError 的子类的实例。本规范无法预测可能会遇到内部错误或资源限制的位置,也没有明确规定何时可以报告这些错误

因此,假设您遇到 OutOfMemoryError 或 UnknownError ,您无能为力,一旦您的 vritualmashine 无法正常工作,您将无法为用户提供任何帮助,因为您的程序也无法正常工作,除了您不知道什么时候,点,以及它发生的原因,因为它不是由您的程序引起的代码错误。

于 2012-11-22T06:52:09.960 回答