我一直在阅读JLS,但我遇到了11.1.3. Asynchronous Exceptions部分,我引用了该部分:
大多数异常由于动作而同步发生 它们出现的线程,以及程序中的某个点 指定可能导致此类异常。异步 相反,异常是可能发生的异常 执行程序的任何一点。
和
异步异常仅在以下情况下发生:
[...]
- Java虚拟机中的内部错误或资源限制,阻止它实现的语义 Java编程语言。在这种情况下,异步异常 抛出的是VirtualMachineError的子类的实例。
是否可以捕获此类异常以进行日志记录或通知(因为我认为这样的事情是不可恢复的)?我怎么能实现这样的目标呢?
答案 0 :(得分:14)
您可以像其他任何异常一样捕获此类异常。唯一的问题是它们可能出现在程序中的任何位置,因此很难抓住它们。你基本上必须在run
块中包装所有线程的main
方法和try..catch
方法,但是对于你不能控制的线程你不能这样做(比如摆动EDT,或定时器的线程等。)。
通常不建议捕获Error
的任何子类,因为JVM可能处于不稳定状态,这可能导致进一步的失败(例如,在OutOfMemoryError
的情况下,您可能甚至没有足够的内存来处理异常处理)。但是,记录是在我眼中捕获Error
的正当理由。
我建议的解决方案是uncaught exception handler使用setting it as the default exception handler。在此处理程序中,如果未在代码中的任何位置捕获它们,您将获得所有异常和错误,并且您可以尝试记录它们。
答案 1 :(得分:3)
没有必要捕获这些异常(VirtualMachineError的子类),因为你没有关于pogram在哪种状态下的不确定性,Doc说明虚拟机错误:
Java虚拟机实现抛出一个对象 当一个类的VirtualMethodError的子类的实例 内部错误或资源限制阻止它实现 本章描述的语义。 此规范不能 预测内部错误或资源限制可能在哪里 遇到并且没有准确地说明何时可以报告。
所以假设你遇到OutOfMemoryError或UnknownError,你可以做很多事情,一旦你的vritualmashine无法正常工作,你就无法为用户提供任何帮助,因为你的程序也不能正常工作,除此之外你不知道它是什么时间,点和原因,因为它不是由你的程序引起的代码错误。