Java Asynchronous Exceptions: Can I catch them?

2019-02-08 07:18发布

问题:

I have been reading the JLS and I encountered the section 11.1.3. Asynchronous Exceptions from which I quote:

Most exceptions occur synchronously as a result of an action by the thread in which they occur, and at a point in the program that is specified to possibly result in such an exception. An asynchronous exception is, by contrast, an exception that can potentially occur at any point in the execution of a program.

And

Asynchronous exceptions occur only as a result of:

[...]

  • An internal error or resource limitation in the Java virtual machine that prevents it from implementing the semantics of the Java programming language. In this case, the asynchronous exception that is thrown is an instance of a subclass of VirtualMachineError.

Is it possible to catch such exceptions for logging purposes or notification (because I believe such thing is unrecoverable)? How can I achieve such thing?

回答1:

You can catch such exceptions just like any other exception. The only problem is that they may occur at any place in your program, so catching them reliably is hard. You would basically have to wrap the run method of all threads and the main method in a try..catch block, but you can't do that for threads you don't control (like the Swing EDT, or threads for timers etc.).

Also catching any subclass of Error is usually not recommended, because the JVM may be in an unstable state, which might lead to a further failure (for example in the case of OutOfMemoryError, you might not even have enough memory to to the exception handling). However, logging would be a valid reason for catching Errors in my eyes.

My suggested solution would be to use an uncaught exception handler for this by setting it as the default exception handler. In this handler you will get all exceptions and errors, if they are not caught anywhere in the code, and you can try to log them.



回答2:

There is no point of catching these exceptions (Subclasses of VirtualMachineError) as you have no indecattion in which state the pogram is at the point, the Doc saies about Virtual Machine Errors:

A Java virtual machine implementation throws an object that is an instance of a subclass of the class VirtualMethodError when an internal error or resource limitation prevents it from implementing the semantics described in this chapter. This specification cannot predict where internal errors or resource limitations may be encountered and does not mandate precisely when they can be reported.

so assuming you get in an OutOfMemoryError or an UnknownError there isnt much you can do about it, and once your vritualmashine doesnt work properly you cant provide the user anyhelp as your program isnt working properly as well, besides you have no idea at what time, point, and reason it happends since its not a code error that was caused from your program.