捕获的异常数量是否会影响try-code的性能?

时间:2010-08-10 08:10:47

标签: java performance exception exception-handling

我经常阅读,与普通代码相比,使用try-catch非常慢。 现在我想知道捕获的异常数是否会影响代码的性能。

所以

try{
  ...
}
catch(StrangeException e){
  ...
}

慢于

try{
  ...
}
catch(StrangeException e){
  ...
}
catch(MysteriousException e){
  ...
}
catch(FrighteningException e){
  ...
}

当然,我只是引用try-clause中的代码,如果没有捕获异常。

5 个答案:

答案 0 :(得分:5)

你读过的是错的。真正抛出异常会产生很大的开销 - 通常在没有异常时开销很小。一个例外是它可能会影响内联 - 所以如果你有一个在紧密循环中调用的方法,你可能会发现它没有内联,如果它有try / catch块。同样地,代码的存在可能会影响缓存一致性和其他细微之处......但在大多数情况下,不会成为瓶颈。

我不认为我曾经看到现实生活中没有抛出异常的情况,但尝试/捕获块一直是性能问题。与以往一样,您应该编写尽可能最干净的代码,并测试它的执行方式。出于性能原因,只有当您明确证明所需的更改有用时,才考虑将理想设计弯曲成形状。

答案 1 :(得分:2)

如果实际没有抛出异常,则try / catch块的开销基本上为零。 catch子句的数量没有区别。

异常的成本在实际被抛出时

  • 由于fillInStackTrace()步骤的成本,构建异常对象非常昂贵。这必须创建并初始化包含当前线程堆栈上所有帧的关键细节的数据结构。在最坏的情况下,可能会有成千上万的。

  • 投掷和捕获异常有点贵。在最坏的情况下,JVM需要为每个try / catch块的每个instanceof子句执行等效的catch。这就是拥有大量catch条款可能会对绩效产生影响的地方。

答案 2 :(得分:0)

唯一能够确定性能问题的方法是自己仔细测试。

但是如果你让我打赌,我敢打赌,它根本没有产生可测量的差异,即使使用try / catch而不使用它也没有太大的区别,只要没有实际上抛出异常(在正常情况下它们不应该是异常的)。

答案 3 :(得分:0)

就我以前记得的读取字节码而言,catch子句的数量对性能没有显着影响。

当发生异常时,JVM知道跳转到实现catch子句的字节码序列,方法是在作为类字节码一部分的表中查找异常。通常,捕获异常的每个方法都与作为类文件一部分的异常表以及方法的字节码相关联。异常表为每个try-block捕获的每个异常都有一个条目。每个条目包含:起点和终点,要跳转到的字节码序列中的程序计数器(PC)偏移量,以及正被捕获的异常类型(即类)的常量池索引。

如果在执行方法期间抛出异常,JVM将在异常表中搜索匹配项。如果当前PC在条目指定的范围内,并且抛出的异常类是条目指定的异常类(或者是其子类),则会发生匹配。

因此,您的问题的答案取决于此搜索的实施方式。据我所知,JVM按照表中条目出现的顺序搜索表,当找到第一个匹配时,JVM将PC设置为新位置并从那里继续执行。

我认为,除非你有很多例外,否则你不会注意到重大影响,但如果我是你,如果这个问题对我来说很重要,我会在你正在使用的特定JVM上对此进行基准测试。

大利

答案 4 :(得分:0)

我确实记得读过有人对此进行了测试,并发现在这种情况下性能实际上受到影响,即使你可能不会期望它。 (快速谷歌搜索没有显示出来,所以我不记得有多少捕获块,或者它找到了哪个Java版本。)