当前位置:首页 > 虚拟机 > 正文

java看虚拟机运行过程(java虚拟机运行原理)

Java的详细运行步骤

Java程序从源文件的创建到程序的执行,主要经历两个步骤:1、源文件被编译器编译成字节码(ByteCode)
2、字节码被解释并执行通过Java虚拟机。由于Java程序必须由JVM编译、解释和执行,因此Java被称为“半解释”语言。
下面将通过Java程序来说明Java程序从编译到最终执行的整个过程。代码如下:
//
publicclassMainApp{
publicstaticvoidmain(String[]args){
Animalanimal=newAnimal("Puppy");
ame();
//
publicclassAnimal{
publicStringname;
publicAnimal(Stringname){
=name;
}
publicvoidprintName(){
n("动物["+name+"]");
}
}
段落1(编译):创建源文件后,程序首先编译为.class文件。Java编译一个类时,如果这个类所依赖的类还没有编译过,编译器会先编译依赖的类,然后再引用它。否则,将直接引用。这有点像make。如果Java编译器在指定目录下找不到该类所依赖的类的.class文件或.java源文件,编译器会报“cantfindsymbol”错误。
编译后的字节码文件格式主要分为两部分:常量池和字节码。常量池记录了代码中出现的所有标记(类名、成员变量名等)和符号引用(引用、成员变量引用等);字节码存储类中每个的字节码。以下是的反汇编结果。我们可以清楚地看到.class文件的结构:
第2步(执行):Java类的执行过程大致可以分为两个过程:1.加载类2.执行类。需要注意的是,只有当程序次主动使用某个类时,JVM才会加载该类。也就是说,JVM不会一开始就把程序的所有类都加载到内存中,而是只在需要使用的时候加载它们,而且只加载一次。
以下是运行该程序的详细步骤:
编译Java程序并得到文件后,在命令行中输入javaAppMain。会启动一个jvm进程。jvm进程从类路径中找到一个名为的二进制文件,并将MainApp类的信息加载到运行时数据区的区中。这个过程称为加载MainApp类。
然后JVM找到AppMain的main函数入口,开始执行main函数。
主函数的条命令是Animalanimal=newAnimal("Puppy");它允许JVM创建一个Animal对象。然而,目前区中还没有Animal类的信息,因此JVM立即加载Animal类并Animal。有关类类型的信息放置在区中。
加载Animal类后,Java虚拟机做的件事就是在堆区为一个新的Animal实例分配内存,然后调用构造函数来初始化Animal实例。这个Animal实例包含一个指向区的指。对Animal类的类型信息的引用(包含表和Java动态绑定的底层实现)。
当使用ame()时,JVM根据Animal引用找到Animal对象,然后根据Animal对象保留的引用定位到区中包含Animal类类型信息的表并获取printName()函数字节码的。
开始执行printName()函数。
特别说明:Java类中所有public和protected实例均采用动态绑定机制,所有私有、静态、构造函数和初始化均采用静态绑定机制。当使用动态绑定机制时,会使用表,但使用静态绑定时则不会。

简述Java程序从编写到运行的基本步骤,并说明Java的基本工作原理

Java编译原理:
Java虚拟机(JVM)是​​一个虚构的能够执行Java代码的计算机。只要根据JVM规范将解释器移植到特定计算机上,就可以保证任何编译后的Java代码都将在该上运行。
1、Java源文件的编译、、解释和执行
Java应用程序的开发周期包括编译、、解释和执行。Java编译器将Java源程序翻译成可执行的JVM字节码。这个编译过程与C/C++编译略有不同。当C编译器编译代码生成对象时,生成的代码可以在特定的硬件平台上运行。因此,在编译过程中,编译器通过查表将所有符号引用转换为特定的内存偏移量,以确保程序运行。Java编译器不会将对变量和的引用编译为数字引用,也不会确定程序执行期间的内存布局,而是将这些符号引用信息存储在解释器在运行时创建的字节码中。然后查看表以确定的。这有效地保证了Java的可移植性和安全性。
执行JVM字节码的工作是由解释器完成的。解释和执行过程分为三个部分:加载代码、验证代码、执行代码。加载代码的工作是由“类加载器”完成的。类加载器负责加载运行程序所需的所有代码,包括从程序代码中的类继承的类以及从中调用的类。当类加载器加载一个类时,该类被放置在它自己的命名空间中。除了通过符号引用其名称空间之外的类之外,类没有其他方式可以影响其他类。这台计算机上的所有类都在同一个空间中,所有从外部导入的类都有自己的命名空间。这使得本地类可以通过共享相同的命名空间来获得更高的运行效率,同时保证它们与外部导入的类不会互相影响。一旦加载了运行程序所需的所有类,解释器就可以确定整个可执行程序的内存布局。解释器建立匹配和查找表以引用特定符号和空间。通过在这个阶段确定代码的内存布局,Java很好地解决了因超类变化而导致子类崩溃的问题,同时也防止了代码非法访问。
然后由字节码检查器检查上传的代码。验证器可以检测各种错误,例如作数堆栈溢出和无效数据类型转换。验证通过后,代码开始执行。
<1.即时编译方式:解释器首先将字节码编译成机器码,然后执行机器码。
​2、解释执行方式:解释器通过每次解释执行一小部分代码来完成Java字节码程序的全部作。
通常采用第二种。由于JVM规范描述足够灵活,字节码到机器码的翻译效率很高。对于那些需要高执行速度的应用程序,解释器可以将Java字节码即时编译为机器代码,从而保证Java代码的可移植性和高性能。