详解 JVM 字节码(9)

作者: zidea | 来源:发表于2019-05-04 13:01 被阅读38次
    jvm
    今天来看一看字节码中的异常处理表
    public class ReadFileHelper {
    
        public void readFile(){
            try {
                InputStream inputStream = new FileInputStream("test.txt");
                ServerSocket serverSocket = new ServerSocket(4200);
                serverSocket.accept();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                System.out.println("call finally method...");
            }
        }
    }
    
    
    • StackMap Table 在 JDK 1.7 以后进行静态数据校验,


      code 助记符
    • new : 创建一个新的对象
    • dup :
    public void readFile()
    
     stack=3, locals=4, args_size=1
    
    • stack=3:最大深度
    • args_size=1 : 这里在readFile()有一个参数为 this。
    • locals=4 : 局部变量为
      1. this
      2. inputStream
      3. serverSocket
      4. ex
        虽然有 3 catch 来捕获对象,但是只是走一个 catch 所以异常对象只会一个作为局部变量。

    每一个 exception_table(异常处理表)表项由 start_pc, end_pc, handler_pc , catch_type 组成。

    • start_pc 和 end_pc 表示在 code 数组中的从 start_pc 到 end_pc 处(包括 start_pc, 不包含 end_pc) 的指令抛出的异常会由这个表项来处理
    • handler_pc 表示处理异常的代码的开始处。catch_type 表示会被处理的异常类型,指向常量池里的一个异常类。当 catch_type 为 0 时,表示处理所有异常。
      发生异常会使用goto语句进行跳转到异常处理的位置。
    jclasslib code
    • new :创建对象
    • dup : 复制操作栈的顶层然后入栈
    • ldc :将常量池获取信息
    • inovkespecial : 调用父类构造方法
    • astore_1 : new FileInputStream 创建对象复制给 inputStream 局部变量进行存储
      下面同上
    • pop 从栈进行弹出
    • getstatic 调用 System.out.Print 静态方法
    异常表
    • 异常表最后一个 any 表示处理以上列出异常以外,都有此异常处理来处理。
    • 0 -26 出现了 FileNotFoundException 异常就会转到 37 进行处理,astore_1赋值给局部变量。
    • 0 - 26 如果出现对应IOException 就会跳转 37 进行处理,astore_1赋值给局部变量。

    字节码中 Java 对异常的处理

    • 统一采用异常表的方法来对异常进行处理
    • 当异常处理存在 finally 语句块,现在 JVM 将 finally 的语句块字节码拼接到每一个 catch 块后。

    相关文章

      网友评论

        本文标题:详解 JVM 字节码(9)

        本文链接:https://www.haomeiwen.com/subject/btwtoqtx.html