我正在处理一个简单的应用程序,现在我不太确定如何处理执行应用程序时发生的错误。我特别担心OutOfMemoryError
。例如:
try{
while(true){
//do some job
}
} catch (Exception e){
System.out.println("Exception occured");
} catch (Throwable t){
//log entry of abnormal termination
System.exit(1);
} finally {
//Terminate application normally
}
这是处理这种情况的正确方法吗?我的意思是尝试在finally块中正常终止应用程序,并在catch(Throwable t)
中杀死JVM。
问题是,如果finally
被抛出,OutOfMemoryError
永远不会被执行。
答案 0 :(得分:3)
我认为甚至不需要,如果你想在OutOfMemoryException
上杀死你的JVM,你可以包含一些JVM标志:
-XX:OnOutOfMemoryError="kill -9 %p"
根据您正在做的事情,点击OutOfMemoryException
时可以释放一些内存,并且最好明确尝试捕捉OutOfMemoryException
而不是抓住{{} {1}}包括可以抛出的所有内容。
答案 1 :(得分:1)
如果是单线程应用程序,您只需记录OOM,让VM正常完成,不要调用System.exit()。如果它是多线程应用程序,您需要有一个关闭它的策略。在每种情况下,由您决定在需要关闭应用程序时应该处理哪些资源以及应该如何处理。你担心最终不会在System.exit()之后调用,如果你有更多的线程它们会被杀死而你无法控制的时候,它们也没有机会进行任何终结。如果您想要优雅地关闭您的应用程序,那么您需要以这样的方式对其进行编程以获得执行此操作的逻辑。
答案 2 :(得分:1)
如果您在System.exit(...)
块中为catch
调用某个异常,则在捕获到异常时将不会执行finally
块。
假设这就是您想要发生的事情......那么您已经正确编码了异常处理。
这是解决这个问题的“正确”方法吗?好吧,如果这是您想要发生的事情(即,如果您想要任何Error
例外以导致跳过正常终止逻辑)那么它是正确的。但最终,你需要自己决定。
话虽如此,如果您担心您的应用程序因内存不足而无法执行终止,那么您可以执行以下操作:
try {
int[] reserved = new int[1,000,000];
while(true){
//do some job
}
} catch (Exception e){
System.out.println("Exception occured");
} catch (Throwable t){
//log entry of abnormal termination
}
// Terminate application normally << HERE
如果JVM抛出OOME,当你到达“HERE”点时,堆中会有8MB的可回收垃圾。如果终止代码填满堆(再次),则GC将回收该垃圾,并且应该有足够的空间来完成终止。