2.10 异常

  java虚拟机中的异常用Throwable类或者它的子类的实例来表示。抛出一个异常会导致立即非本地(an inmediate nolocal)的控制转移,从发生异常的地方跳到处理异常的地方。

  大多数异常是在当前线程执行某些操作时同步发生的。对应的,非同步异常可能发生在程序执行的任何阶段。java虚拟机会由于下面三个原因中的一个抛出异常:

  • 执行athrow指令
  • java虚拟机同步检测到非正常的执行情况。这些异常不是在程序中的任意点抛出的,而是在执行以下指令后同步抛出:
    • 指明异常作为一种可能的结果,例如

      • 当指令包含违反Java编程语言语义的操作时,例如在访问数组边界外的元素。
      • 程序在加载或者连接的过程中出现错误
    • 导致了使用了超过限制的资源,例如使用了太多的内存。
  • 异步异常出现的原因:
    • 调用了Thread或者ThreadGroup类的stop方法,或者
    • java虚拟机实现出现了内部错误

    一个线程调用stop方法会影响另外一个线程,或者一个限制组的所有线程。它们是异步的异常,因为它们可能出现线程执行的任何位置。内部异常被认为是异步的。

  Java虚拟机可能允许在抛出异步异常之前执行少量但有限制的指令。这种延迟允许优化代码检测并抛出这些异常,这些异常可以在符合Java编程语言语义的情况下处理。

  一个简单的实现可能在每个控件传输指令处轮询异步异常。由于程序的大小是有限的,这就为检测异步异常的总延迟提供了一个界限。由于控制传输之间不会发生异步异常,代码生成器具有一定的灵活性,可以在控制传输之间重新排序计算,以获得更好的性能。The paper Polling Efficiently on Stock Hardware by Marc Feeley, Proc. 1993 Conference on Functional Programming and Computer Architecture, Copenhagen, Denmark, pp. 179–187, is recommended as further reading. 

  java虚拟机抛出的异常是精确的:当发生控制转移时,在抛出异常之前执行的指令的所有效果必须可以被观察到。异常抛出之后的指令应当是没有被执行过。如果虚拟机进行了代码优化,导致了异常抛出之后的代码可能被执行了,那么必须保证执行这些代码造成的影响对用户是不可见的。

  java虚拟机中的每一个方法都会关联0个或者多个异常处理器(exception handlers)。异常处理器描述了其在方法代码中的有效作用范围(通过字节码偏移量来描述)、能处理的异常类型以及处理异常的代码所在的位置。如果导致异常的指令的偏移量在异常处理程序的偏移范围内,并且异常类型与异常处理器处理的异常类的子类相同,则异常与异常处理器匹配。。当抛出异常时,Java虚拟机在当前方法中搜索匹配的异常处理器。如果找到匹配的异常处理器,系统将跳转到异常处理器指定的异常处理代码处执行。

  如果当前方法没有产生异常所对应的异常处理器,当前方法调用会立即结束,当前方法中的操作数栈和局部变量表会被丢弃,栈帧被出栈,恢复调用者方法的栈帧。然后这个异常沿着方法调用链,在调用者栈帧等的上下文中被重新抛出。在到达方法调用链顶层前没有找到合适的异常处理器,异常抛出的线程将被终止。

  方法的异常处理器的顺序在搜索匹配时重要的。在class文件中,每个方法的异常处理器时存在表中。在运行时,当异常抛出时,java虚拟机按照顺序搜索当前方法的异常处理器,顺序是根据它们出现在class文件表的位置,从表的起始处开始。

  请注意,Java虚拟机不强制嵌套或对方法的异常表项进行任何排序。所以java语言中对异常处理的语义,实际上是通过编译器适当安排异常处理器在表中的顺序来协助完成的。在class文件中定义了明确的异常处理器查找顺序,才能确保无论class文件时通过何种途径产生的,java续集及执行时都能有一致的行为表现。

  

  

java虚拟机规范(se8)——java虚拟机结构(五)的更多相关文章

  1. java虚拟机规范(se8)——java虚拟机结构(一)

    本文翻译自:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html 第二章 虚拟机结构 本文档描述了一个抽象的虚拟机规范,并不描述 ...

  2. java虚拟机规范(se8)——java虚拟机结构(六)

    2.11 指令集简介 java虚拟机指令由一个字节的操作码,接着时0个或多个操作数组成,操作码描述了执行的操作,操作数提供了操作所需的参数或者数据.许多指令没有操作数只包含一个操作码. 如果忽略异常处 ...

  3. java虚拟机规范(se8)——java虚拟机结构(二)

    2.5 运行时数据区域 java虚拟机定义了多个用于程序执行期间的运行时数据区域.这些数据区域中一些随着java虚拟机的启动而创建,随着虚拟机的退出而销毁.其他的数据区域时和线程相关的.线程相关数据区 ...

  4. java虚拟机规范(se8)——java虚拟机的编译(四)

    3.12 抛出和处理异常 在程序中使用throw关键字来抛出异常.编译结果很简单. void cantBeZero(int i) throws TestExc { if (i == 0) { thro ...

  5. java虚拟机规范(se8)——java虚拟机的编译(一)

    本文翻译自:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html 第三章 java虚拟机的编译 java虚拟机是设计用来支持ja ...

  6. java虚拟机规范(se8)——java虚拟机结构(三)

    2.6. 栈帧 栈帧用于存储数据和部分结果,同样也用于执行动态链接,返回方法的值和分派异常. 当方法被调用的时候会创建一个新的栈帧.当一个方法调用结束时,它对应的栈帧就被销毁了,不管是正常调用结束还是 ...

  7. java虚拟机规范(se8)——java虚拟机结构(四)

    2.7 对象的表示 java虚拟机并不要求对象满足任何特定的内部结构. 在Oracle的一些Java虚拟机实现中,对类实例的引用是指向句柄的指针,该句柄本身是一对指针:一个指向包含对象方法的表和指向表 ...

  8. java虚拟机规范(se8)——java虚拟机的编译(三)

    3.6 接受参数 如果n个参数传给一个实例的方法,按照约定,它们被接受并放在这个新方法创建的栈帧中的局部变量表里,在局部变量表中的序号从1到n.这些参数按照它们传递过来的顺序存放.例如: int ad ...

  9. java虚拟机规范(se8)——java虚拟机的编译(二)

    3.3 算术运算 java虚拟机通常在操作数栈上进行算术运算(例外情况是iinc指令,它直接增加一个局部变量的值).例如下面的align2grain()方法,它的作用是将int值对齐到2的指定次幂: ...

随机推荐

  1. C++学习记录(留坑)

    #include <iostream> #include <ctime> #include <fstream> ///文件打开有o.i权限 #include < ...

  2. MT【109】线面角最大时为二面角平面角

    解答:如图设C到$\alpha$面的距离为$d_1,C_1$到虚线距离为$d_2$ 所求距离$d=d_1+d_2=|AC|sin\theta+|CC_1|cos\theta=4\sqrt{2}sin\ ...

  3. 【agc002f】Leftmost Ball(动态规划)

    [agc002f]Leftmost Ball(动态规划) 题面 atcoder 洛谷 题解 我们从前往后依次把每个颜色按顺序来放,那么如果当前放的是某种颜色的第一个球,那么放的就会变成\(0\)号颜色 ...

  4. Winform Treeview 的按需加载

    最近项目里用到treeview,原先设计的是一开始就把所有数据都加载到treeview里,后来发现客户的数据量实在太大,加载所有数据要2分钟,这个是客户没法接受的.后来就考虑到用户也不是一开始就要看所 ...

  5. java执行shell脚本并输出执行情况

    1.脚本test.sh,置于/Users/hdwang目录下 #!/bin/sh cd /Users/hdwang echo ls:`ls` ;i<=;i++)); do + ); sleep ...

  6. 2019.2.28&2019.3.1 考试

    因为没A/改几道题,就一起写了 题目在LOJ上都能找到 2019.2.28 100+20+12 前两个小时一直在睡觉+想题也没思路,我太菜了 T1 洗衣服 分开处理出洗衣服和烘干的时间,然后一边正着排 ...

  7. 《剑指offer》— JavaScript(33)丑数

    丑数 题目描述 把只包含质因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 思 ...

  8. Eclipse配置Maven的一些问题

    问题1:连接私服 build项目非常缓慢 配置好本地的setting文件后,发现build非常缓慢,照显示的进度,可能要一天才会build后一个项目,同事指导解决方法如下: MyEclipse2017 ...

  9. String.format VS. StrSubstitutor VS. NamedParameterJdbcTemplate

    在Java中,想要用一个字符串模块根据参数的不同来产生不同的字符串,主要有以下两种办法: Java String.format() 在JDK1.5中,String类新增了一个很有用的静态方法Strin ...

  10. REDIS 缓存的穿透,雪崩和热点key

    穿透 穿透:频繁查询一个不存在的数据,由于缓存不命中,每次都要查询持久层.从而失去缓存的意义. 解决办法:①用一个bitmap和n个hash函数做布隆过滤器过滤没有在缓存的键.   ②持久层查询不到就 ...