我正在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退出是因为内存已用完吗?
我看到两种可能性:
- 你误以为
try
块抛出了一个异常:也许没有抛出异常,或者可能抛出了一个异常,但它是在try
-block 结束之前被捕获的。- 您可以通过在
try
-block 的末尾和任何可能过早退出try
-block 的return
或break
或continue
语句之前添加日志记录语句来仔细检查。
- 您可以通过在
- 您捕获的异常类型不是通常的
java.lang.Throwable
,而是您显式定义和/或导入的其他Throwable
类。- 您可以通过将
Throwable
更改为更明确的java.lang.Throwable
来仔细检查。
- 您可以通过将
我发现 catch 子句从未执行,但当我的程序退出时会执行最终日志。
这意味着try
块不会抛出异常1。
无论 try 块和所选的 catch 块(如果有)如何终止,都将执行finally
块。
但是,也可能是您对捕获条款的"发现"不正确。
谁能告诉我这是怎么发生的?
见上文。
我很确定try{}中的代码退出时出现问题,而不是正常退出。
凭什么证据?
由于 try{} 中的代码正在执行 while 循环并消耗大量内存,那么原因可能是 jvm 退出是因为内存已用完吗?
这将导致OutOfMemoryError
,Throwable
的catch
块应该抓住这一点。
try
块可能引发异常并且 Throwable
的捕获似乎不起作用的唯一情况是,如果catch
本身抛出另一个异常......在它执行您尝试执行的操作(即错误)之前(即错误.log)。 如果第一个异常是OutOfMemoryError
,则可能出现这种情况。 如果在退出try
块的作用域时 GC 无法释放任何内存,则在日志记录代码需要创建对象时,可能会引发第二个 OOME。
应该注意的是,捕捉Throwable
是危险的。 它捕获不应捕获的各种Error
异常,因为它们不可恢复。 坏事可能会发生。
1 - 理论上也有可能你的代码中的Throwable
不是java.lang.Throwable
,但只有疯子才会编写和使用他们自己的Throwable
异常类......然后忘记他们已经这样做了:-)。