java代码执行原理图 java程序运行代码( 三 )


·与异常相匹配的catch子句应该符合下面的条件:造成异常的指令在其指令范围之内,发生的异常类型是其能处理的异常类型的子类型 。如果找到了匹配的catch子句,那么系统转移到指定的异常处理块处执行;如果没有找到异常处理块,重复寻找匹配的catch子句的过程,直到当前方法的所有嵌套的 catch子句都被检查过 。
·由于虚拟机从第一个匹配的catch子句处继续执行,所以catch子句表中的顺序是很重要的 。因为Java代码是结构化的,因此总可以把某个方法的所有的异常处理器都按序排列到一个表中,对任意可能的程序计数器的值,都可以用线性的顺序找到合适的异常处理块,以处理在该程序计数器值下发生的异常情况 。
·如果找不到匹配的catch子句,那么当前方法得到一个"未截获异常"的结果并返回到当前方法的调用者,好像异常刚刚在其调用者中发生一样 。如果在调用者中仍然没有找到相应的异常处理块,那么这种错误传播将被继续下去 。如果错误被传播到最顶层,那么系统将调用一个缺省的异常处理块 。
(3)*作数栈区 机器指令只从*作数栈中取*作数,对它们进行*作,并把结果返回到栈中 。选择栈结构的原因是:在只有少量寄存器或非通用寄存器的机器(如Intel486)上,也能够高效地模拟虚拟机的行为 。*作数栈是32位的 。它用于给方法传递参数,并从方法接收结果,也用于支持*作的参数,并保存*作的结果 。例如,iadd指令将两个整数相加 。相加的两个整数应该是*作数栈顶的两个字 。这两个字是由先前的指令压进堆栈的 。这两个整数将从堆栈弹出、相加,并把结果压回到*作数栈中 。
每个原始数据类型都有专门的指令对它们进行必须的*作 。每个*作数在栈中需要一个存储位置,除了long和double型,它们需要两个位置 。* 作数只能被适用于其类型的*作符所*作 。例如,压入两个int类型的数,如果把它们当作是一个long类型的数则是非法的 。在Sun的虚拟机实现中,这个限制由字节码验证器强制实行 。但是,有少数*作(*作符dupe和swap),用于对运行时数据区进行*作时是不考虑类型的 。
4.无用单元收集堆
Java的堆是一个运行时数据区,类的实例(对象)从中分配空间 。Java语言具有无用单元收集能力:它不给程序员显式释放对象的能力 。Java不规定具体使用的无用单元收集算法,可以根据系统的需求使用各种各样的算法 。
5.方法区
方法区与传统语言中的编译后代码或是Unix进程中的正文段类似 。它保存方法代码(编译后的java代码)和符号表 。在当前的Java实现中,方法代码不包括在无用单元收集堆中,但计划在将来的版本中实现 。每个类文件包含了一个Java类或一个Java界面的编译后的代码 。可以说类文件是Java 语言的执行代码文件 。为了保证类文件的平台无关性,Java虚拟机规范中对类文件的格式也作了详细的说明 。其具体细节请参考Sun公司的Java虚拟机规范 。
内容来源于网上 。
java程序运行原理?先编译 , 利用java编译器(JDK自带的工具)把java文件转换成字节码文件(.class文件)
这个时候生成的字节码也不是计算机能识别的,还要让jvm也就是java虚拟机解读,java虚拟机首先读入字节码、对字节码进行正确性检查,针对客户计算机平台生成对应的机器指令 , 由客户机器执行机器指令 。
希望对你有帮助
java虚拟机工作原理?从宏观上介绍一下Java虚拟机的工作原理 。从最初编写的Java源文件(.java文件)是如何一步步执行的,如下图所示,首先Java源文件经过前端编译器(javac或ECJ)将.java文件编译为Java字节码文件,然后JRE加载Java字节码文件 , 载入系统分配给JVM的内存区,然后执行引擎解释或编译类文件,再由即时编译器将字节码转化为机器码 。主要介绍下图中的类加载器和运行时数据区两个部分 。

推荐阅读