从JVM视角分析try...catch...性能

栏目: Java · 发布时间: 7年前

内容简介:随便写一个简单的程序看一下字节码指令过程:可以看到有个异常表:

随便写一个简单的程序

public class Test {
    public static void main(String[] args) {
        int a = 0,b=2;
        try {
            a = b/0;
        }catch (Exception e){
            a = 1;
        }
    }
}
复制代码

看一下字节码指令过程:

public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=4, args_size=1
         0: iconst_0        push 0
         1: istore_1        pop并保存到局部变量1
         2: iconst_2       push 2
         3: istore_2       pop并保存到局部变量2
         4: iload_2        从局部变量里拿出并push
         5: iconst_0        push 0 
         6: idiv          栈顶两数相除
         7: istore_1
         8: goto          14
        11: astore_3
        12: iconst_1
        13: istore_1
        14: return
      Exception table:
         from    to  target type
             4     8    11   Class java/lang/Exception
      LineNumberTable:
        line 8: 0
        line 10: 4
        line 13: 8
        line 11: 11
        line 12: 12
        line 14: 14
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
           12       2     3     e   Ljava/lang/Exception;
            0      15     0  args   [Ljava/lang/String;
            2      13     1     a   I
            4      11     2     b   I
      StackMapTable: number_of_entries = 2
        frame_type = 255 /* full_frame */
          offset_delta = 11
          locals = [ class "[Ljava/lang/String;", int, int ]
          stack = [ class java/lang/Exception ]
        frame_type = 2 /* same */
}
复制代码

可以看到有个异常表:

Exception table:
         from    to  target type
             4     8    11   Class java/lang/Exception
复制代码

from 表示 try catch 的开始地址 to 表示 try catch 的结束地址 target 表示异常的处理起始位 type 表示异常类名称

代码运行时出错时,会先判断出错位置是否在 from - to 的范围,如果是,则从 target 标志位往下执行,如果没有出错,直接 gotoreturn 。可以看出,如果代码不出错的话,性能几乎是不受影响的,和正常的代码执行是一样的。

那异常处理耗时是什么个概念呢?

实验二:异常处理耗时测试

public class Test {
    public static void main(String[] args) {
        int a = 0,b=2;
        long startTime = System.nanoTime();
        for (int i = 10; i>0;i--){
            try {
                a = b/i;
            }catch (Exception e){
                a = 1;
            }finally {

            }
        }
        long runTime = System.nanoTime()-startTime;
        System.out.println(runTime);
    }
}
复制代码

我只需要把 i>0 改成 i>=0 ,程序遍会进行一次异常处理,因为除数不能为0.

我在修改之前(无异常运行),运行的结果是 1133 修改之后(会出现除数为0异常),运行结果是 44177

当然,这个结果和cpu的算力有关,多次运行结果相差无几。

所以,可以看出一旦程序进入到catch里,是非常耗资源的。

那try catch 在for循环外面或者里面,哪个更好呢?

实验三:for循环在try里面

public class Test {
    public static void main(String[] args) {
        int a = 0,b=2;
        long startTime = System.nanoTime();
        try {
            for (int i = 10; i>=0;i--){
                    a = b/i;
            }
        }catch (Exception e){
            a = 1;
        }finally {
            long runTime = System.nanoTime()-startTime;
            System.out.println(runTime);
        }
    }
}
复制代码

运行多次的控制台输出:

46820     48708 54749  47953   46820  45310
复制代码
public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=5, args_size=1
         0: iconst_0
         1: istore_1
         2: iconst_2
         3: istore_2
         4: bipush        10
         6: istore_3
         7: iload_3
         8: iflt          21
        11: iload_2
        12: iload_3
        13: idiv
        14: istore_1
        15: iinc          3, -1
        18: goto          7
        21: goto          35
        24: astore_3
        25: iconst_1
        26: istore_1
        27: goto          35
        30: astore        4
        32: aload         4
        34: athrow
        35: return
      Exception table:
         from    to  target type
             4    21    24   Class java/lang/Exception
             4    21    30   any
            24    27    30   any
            30    32    30   any
复制代码

实验四:try在for循环外面

public class Test {
    public static void main(String[] args) {
        int a = 0,b=2;
        long startTime = System.nanoTime();
        for (int i = 10; i>=0;i--){
            try {
                a = b/i;
            }catch (Exception e){
                a = 1;
            }finally {

            }
        }
                long runTime = System.nanoTime()-startTime;
                System.out.println(runTime);
    }
}
复制代码

控制台打印:

42289  47953  49463  45688  45310
复制代码
public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=6, args_size=1
         0: iconst_0
         1: istore_1
         2: iconst_2
         3: istore_2
         4: bipush        10
         6: istore_3
         7: iload_3
         8: iflt          36
        11: iload_2
        12: iload_3
        13: idiv
        14: istore_1
        15: goto          30
        18: astore        4
        20: iconst_1
        21: istore_1
        22: goto          30
        25: astore        5
        27: aload         5
        29: athrow
        30: iinc          3, -1
        33: goto          7
        36: return
      Exception table:
         from    to  target type
            11    15    18   Class java/lang/Exception
            11    15    25   any
            18    22    25   any
            25    27    25   any
复制代码

综合实验三和实验四,我们发现无论从运行时长还是从字节码指令的角度看,它两的性能可以说是一样的。并没有你感觉到的for循环里放try代码会冗余、资源消耗加倍的问题。

但是从运行逻辑来看,两个是有点不同的,实验三中,因为for在try catch里,所以jvm在编译的时候,把异常处理放在for循环后面才进行。即: 第24-27行 ;实验四中,异常处理是在for循环内部的,即: 第18-22行 。大同小异。

以上仅个人测试观点,如果有误请在下方留言,谢谢!


以上所述就是小编给大家介绍的《从JVM视角分析try...catch...性能》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Head First Design Patterns

Head First Design Patterns

Elisabeth Freeman、Eric Freeman、Bert Bates、Kathy Sierra、Elisabeth Robson / O'Reilly Media / 2004-11-1 / USD 49.99

You're not alone. At any given moment, somewhere in the world someone struggles with the same software design problems you have. You know you don't want to reinvent the wheel (or worse, a flat tire),......一起来看看 《Head First Design Patterns》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

URL 编码/解码
URL 编码/解码

URL 编码/解码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具