未捕获异常,但程序退出并最终执行



我正在Linux服务器上进行压力测试。但是我发现我的java应用程序总是退出而没有任何错误消息。所以我使用 try-catch-finally 并希望获得有关退出原因的一些信息。代码如下:

try{
// the code which make my program exit without any error log
}catch(Throwable e){
//print some log
}finally{
// print some log
}

我发现 catch 子句从未执行,但当我的程序退出时会执行最终日志。谁能告诉我这是怎么发生的?我很确定try{}中的代码退出时出现问题,而不是正常退出。由于try{}中的代码正在执行while循环并消耗大量内存,那么,原因可能是jvm退出是因为内存已用完吗?

我看到两种可能性:

  1. 你误以为 try 块抛出了一个异常:也许没有抛出异常,或者可能抛出了一个异常,但它是在try -block 结束之前被捕获的。
    • 您可以通过在 try -block 的末尾和任何可能过早退出 try -block 的returnbreakcontinue语句之前添加日志记录语句来仔细检查。
  2. 您捕获的异常类型不是通常的java.lang.Throwable,而是您显式定义和/或导入的其他Throwable类。
    • 您可以通过将Throwable更改为更明确的java.lang.Throwable来仔细检查。

我发现 catch 子句从未执行,但当我的程序退出时会执行最终日志。

这意味着try块不会抛出异常1

无论 try 块和所选的 catch 块(如果有)如何终止,都将执行finally块。

但是,也可能是您对捕获条款的"发现"不正确。

谁能告诉我这是怎么发生的?

见上文。

我很确定try{}中的代码退出时出现问题,而不是正常退出。

凭什么证据?

由于 try{} 中的代码正在执行 while 循环并消耗大量内存,那么原因可能是 jvm 退出是因为内存已用完吗?

这将导致OutOfMemoryErrorThrowablecatch块应该抓住这一点。

try块可能引发异常并且 Throwable 的捕获似乎不起作用的唯一情况是,如果catch本身抛出另一个异常......在它执行您尝试执行的操作(即错误)之前(即错误.log)。 如果第一个异常是OutOfMemoryError,则可能出现这种情况。 如果在退出try块的作用域时 GC 无法释放任何内存,则在日志记录代码需要创建对象时,可能会引发第二个 OOME。


应该注意的是,捕捉Throwable是危险的。 它捕获不应捕获的各种Error异常,因为它们不可恢复。 坏事可能会发生。


1 - 理论上也有可能你的代码中的Throwable不是java.lang.Throwable,但只有疯子才会编写和使用他们自己的Throwable异常类......然后忘记他们已经这样做了:-)。

相关内容

  • 没有找到相关文章

最新更新