java虚拟机结构(概览四)

java虚拟机结构(概览四)

1、异常

java虚拟机里面的异常使用throwable或其子类的实例来表示,抛异常的本质实际是程序控制权的一种即时的、非局部的装换——从异常抛出的的地方转换至处理异常的地方。 绝大数异常的产生都是由于当前线程执行某个操作所导致的,这种可以称为同步异常。与之相对,异步异常可以在程序执行过程中随时发生。java虚拟机中异常的出现总是由于下面三种原因之一导致的。

  athrow字节码指令被执行
  虚拟机同步检测到程序发生了非正常的执行情况,这时异常必将紧接着在发生非正常执行情况的字节码指令之后抛出,而不会在执行程序的过程中随时抛出。例如:
    1、程序所执行的操作可能会引发异常,例如:
      当字节码指令所蕴含的操作违反了java语言的语义,如访问一个超出数组边界范围的元素
      当程序在加载或者连接时出现错误
    2、使用某些资源的时候产生资源限制,例如使用了太多内存
  由于以下原因,导致了异步异常的出现:
    1、调用了Thread或者ThreadGroup的stop方法
    2、java虚拟机实现发生内部错误。

java虚拟机规范允许在异步异常抛出之前额外执行一小段有限的代码,使得代码优化器能够在不违反java语言语义的前提下检测并把这些异常在可处理他们的地方抛出。

2、字节码指令集简介

java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的操作码以及紧随其后的零至多个代表此操作所需的操作数所构成。虚拟机中许多指令并不包含操作数,只有一个操作码。 如果忽略异常处理,那么java虚拟机的解释器通过下面这个伪代码的循环即可有效工作:

  do{
•    自动计算pc寄存器以及pc寄存器的位置所取出的操作码;
•    if(存在操作数)取出操作数;
•    执行操作码所定义的操作;
  }while(处理下一次循环)

操作数的数量以及长度取决于操作码,如果一个操作数的长度超过了一个字节,那么它将会以big-endian顺序存储,即高位在前的字节序。例如,如果要将一个16位长度的无符号整数使用两个无符号字节存储起来(将他们命名为byte1和byte2),那这个16位无符号整数的值就是:(byte1<<8)|byte2。 字节码指令流应当都是单字节对齐的,只有tableswitch和lookupswitch两个指令例外,由于他们的操作数比较特殊,都是以4字节为界划分的,所以当这两个指令的参数位置不是4字节的倍数时,需要预留出相应的空位补全到4字节的倍数以实现对齐。

你可能感兴趣的:(Java)