`
iwindyforest
  • 浏览: 235707 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

try-catch影响性能吗?

阅读更多

try-catch会影响性能吗? try-catch放在循环块里面比放在外面程序运行会慢吗?

看到论坛上有人对try-catch对性能的影响存在疑问,比如:

http://www.iteye.com/topic/1127950

很多想当然的答案是: try-catch放在循环块里面肯定比放在循环块外面慢.

但是, 这个想当然的答案是错误的.

 

加了try-catch块的代码跟没有加的代码运行时的性能是一样的, 没有区别,

区别只是加了try-catch块的代码在抛出异常时, 会有不同的处理逻辑, 仅此而已.

 

stackOverflow的网站上有人也问过类似问题:

http://stackoverflow.com/questions/141560/should-try-catch-go-inside-or-outside-a-loop

老外回答的比较详细.

 

下面是我翻译的一篇解释JVM异常处理机制的文章, 原文来自:

http://www.javaworld.com/article/2076868/learn-java/how-the-java-virtual-machine-handles-exceptions.html

 

static int remainder(int dividend, int divisor)
    throws DivideByZeroException {
    try {
        return dividend % divisor;
    }
    catch (ArithmeticException e) {
        throw new DivideByZeroException();
    }
}

 

 

The main bytecode sequence for remainder:
   0 iload_0               // Push local variable 0 (arg passed as divisor)
   1 iload_1               // Push local variable 1 (arg passed as dividend)
   2 irem                  // Pop divisor, pop dividend, push remainder
   3 ireturn               // Return int on top of stack (the remainder)
The bytecode sequence for the catch (ArithmeticException) clause:
   4 pop                   // Pop the reference to the ArithmeticException
                           // because it isn't used by this catch clause. 
   5 new #5 <Class DivideByZeroException>
                           // Create and push reference to new object of class
                           // DivideByZeroException.
DivideByZeroException
   8 dup           // Duplicate the reference to the new
                           // object on the top of the stack because it 
                           // must be both initialized 
                           // and thrown. The initialization will consume
                           // the copy of the reference created by the dup.
   9 invokenonvirtual #9 <Method DivideByZeroException.<init>()V>
                           // Call the constructor for the DivideByZeroException
                           // to initialize it. This instruction
                           // will pop the top reference to the object.
  12 athrow                // Pop the reference to a Throwable object, in this
                           // case the DivideByZeroException, 
                           // and throw the exception.

 

 

JVM在执行try-catch的字节码的时候, 会维护一张异常表. 如果有异常发生, JVM会从异常表里面查询是否该异常能够被catch住. 每一个能捕获异常的方法都通过这个方法的字节码与它所属类的异常表关联. 每一处声明的try-catch异常都对应异常表中的一个条目.

每一个条目有四列信息: 异常声明的开始行, 结束行, 异常捕获后跳转到的代码计数器(PC)所指向的行数, 还有一个表示捕获的异常类的常量池索引.

异常表是类似于下面这样:

 

Exception table:
   from   to  target type
     0     4     4   <Class java.lang.ArithmeticException>

上面的异常表表明从第0行到第3行(包括)能够捕获ArithmeticException.

try块的结束行在异常表的to这一列中表示, to所指的行数永远比能捕获异常代码的最后一行要大.

这个示例中try块结束行(to)为4, 但是能捕获异常的最大行数为从from(第0行)到最大行数为第3行, 这个范围是, 0到3的闭区间, 对应remainder字节码中的try块中的前4行.

 

这个表中Target列表示当ArithmeticException异常在0-3行被抛出时, 将会被捕获并跳转Target所指向的行数(注意这里只是一个

偏移地址, 不是真实代码行数).

 

如果在执行方法时有一个异常被抛出, JVM就会从异常表中按照条目所出现的顺序查找对应的条目. 如果异常抛出时PC计数器所指向的行数正好落在异常表中某一条目包含的范围内, 并且所抛出的异常正好是异常表中type列所指定的异常(或者所指定异常的子类), 那么JVM就会将PC计数器指向Target偏移量所指向的地址, (进入catch块)继续执行.

 

如果没有在异常表中找到异常, JVM就会将当前栈帧弹出并重新抛出这个异常. 当JVM弹出当前栈帧的时候, 它就会中止当前方法的执行, 返回到调用当前方法的外部方法中, 不过并不会像正常没有异常发生时那样继续执行外部方法, 而是在外部方法中抛出相同的异常, 这样将会导致JVM会在外部方法中重复查询异常表并处理异常的过程.

 

 

0
0
分享到:
评论

相关推荐

    C#中Try-Catch语句真的影响程序性能吗?

    然而,关于Try-Catch语句是否会影响程序性能的问题,一直是开发者们关注的焦点。本文将结合IL(中间语言)分析Try-Catch的内部机制及其对性能的影响。 首先,理解Try-Catch的工作原理对于评估其性能至关重要。在...

    try_catch效率

    为了量化`try-catch`对性能的影响,我们可以编写一段代码,分别在有无`try-catch`的情况下执行相同任务,然后记录并比较运行时间。例如,我们可以计算大量重复操作的执行时间,如文件读写、数据库查询等,这些操作在...

    通过Java代码技巧改善性能

    但是,try-catch语句对系统性能的影响非常糟糕。尤其是在循环体内使用try-catch语句时,对性能的影响将会成倍增加。以下是一个将try-catch应用于循环体内的示例代码: ```java @Test public void test11() { long ...

    js代码-???????

    - 使用`try...catch`语句捕获和处理运行时错误。 - `console.log()`、`console.error()`等调试工具帮助定位问题。 9. **性能优化**: - 适当的缓存策略、减少HTTP请求、优化DOM操作等方法可以提升网页性能。 10...

    Try Catch对效能的影响测试

    这个测试是针对`Try...Catch`块对程序性能影响的一个研究,旨在理解在代码中使用异常处理时可能产生的性能开销。 异常处理是软件开发中的关键组成部分,它允许程序在遇到错误或异常情况时,仍能够优雅地执行,而...

    利用try-catch判断变量是已声明未声明还是未赋值

    `try-catch`语句是处理异常和错误的常用机制,而在这个特定场景中,它被用来区分变量是否已声明但未赋值,或者完全未声明。以下是关于利用`try-catch`来判断变量状态的详细说明。 首先,我们要理解JavaScript中的...

    [] - 2022-09-03 try catch真的会影响性能?居然被骗了好几年....pdf

    互联网资讯,技术简介,IT、AI技术,人工智能

    Java 问答式教程

    - 如何使用try-catch-finally语句?`try { potential_error_code; } catch (ExceptionType e) { handling_code; } finally { always_executed_code; }` 8. **集合框架** - 集合有哪些主要接口和类?如List...

    JAVA面试题

    异常是程序运行时发生的错误,通过try-catch-finally语句块进行处理。 - 自定义异常如何实现? 6. **集合框架** - ArrayList和LinkedList的区别是什么? - HashMap和TreeMap的工作原理是什么?它们的时间复杂度...

    杂谈try-catch-finally异常处理

    相关阅读:再谈异常处理try catch finally 1. 前言 最近这段时间正开发一个店铺管理系统,这个项目定位于给中小型店铺使用的软件系统。简单的说,它处理商品的进货,销售,退货等功能。软件虽小,五脏俱全,里面...

    java经典面试题

    - try-catch-finally块的执行顺序。 5. **类与对象** - 什么是构造函数链?为什么需要构造函数链? - 如何实现深拷贝和浅拷贝? - 详述equals()和hashCode()方法的重要性。 6. **集合框架** - List、Set、Map...

    java常见面试题大集合

    - try-catch-finally语句块的执行顺序是什么? 6. **类与对象** - 如何实现对象的创建和初始化? - 解释一下构造函数的作用和特性。 7. **继承与多态** - 继承有哪些优点?子类和父类之间的关系如何表示? - ...

    Java 的异常处理.pdf

    这种方法更加直接地暴露了可能的异常源,但同样会导致频繁的try-catch调用,可能影响性能。 3. `testDefensiveProgramming`方法:这种方法采用了防御性编程策略,先检查对象是否为null再执行add操作。这种方式避免...

    C++异常处理技巧try/catch/throw/finally/exception

    通过合理地使用`try`、`catch`、`throw`和`exception`等关键字,开发者不仅能够编写更加可靠的代码,还能显著提升程序的可维护性和可读性。 #### 二、C++标准异常处理 ##### 1. 构造和析构中的异常抛出 在C++中,...

    Java异常处理细节分析

    2. **Catch块**:如果`try`块中发生了异常,并且这个异常能被一个或多个`catch`块捕获,那么将执行对应的`catch`块。每个`catch`块都有特定的异常类型,只有当捕获到的异常类型与之匹配时才会执行。 3. **Finally块*...

    互联网高频Java后端面试题20道(适合1~3年)V1.0.72.docx

    try 块包含可能会抛出异常的代码,当异常发生时,程序会立即跳出 try 块,寻找匹配的 catch 块进行处理。catch 块用于捕获并处理特定类型的异常,可以有多个 catch 块处理不同类型的异常。finally 块包含的代码无论...

Global site tag (gtag.js) - Google Analytics