当前位置: 首页 > 科技观察

Java虚拟机与JVM架构

时间:2023-03-12 07:18:46 科技观察

JVM(Java虚拟机)Java虚拟机,java源文件(.java)通过编译器生成字节码文件(.class),字节码文件(.class)通过JVM(Java虚拟机)在解释器然后在特定机器上翻译成机器代码。编译器只需要面向虚拟机,生成虚拟机可以理解的代码,然后解释器将虚拟机代码转换成特定系统的机器码执行即可。每个平台的解释器不一样,但是实现的虚拟机是一样的。Java源程序由编译器编译成字节码,字节码由虚拟机解释执行。虚拟机将每个要执行的字节码发送给解释器,解释器将其翻译成特定机器上的机器。代码,然后在特定的机器上运行它。JVM架构JVM有两种机制,一种是加载一个有适当名称的类(类或接口),称为类加载子系统;另一个负责执行加载的类或接口中包含的指令,称为运行引擎。每个JVM包括五个部分:方法区、堆、Java栈、程序计数器、本地方法栈。这些部分组成的架构图,类加载机制和运行引擎机制如下:它有自己的方法区和堆,JVM中运行的所有线程共享这些区域;当虚拟机加载一个类文件时,它解析二进制数据中包含的类信息,并将它们放在方法域中;程序运行时,JVM把程序初始化的所有对象都放在堆上;而每个线程在创建的时候,都会有自己的程序计数器和Java栈,其中程序计数器中的值指向下一条执行的指令,线程的Java栈中存储的是调用线程的状态Java方法;本地方法调用的状态保存在本地方法栈中,方法栈取决于具体实现。(1)类加载子系统加载、连接和初始化(2)方法区。由所有线程共享。垃圾收集还会清理方法区中未使用类型的对象。A。键入信息。当类加载器加载一个类时,它会从类文件中提取它。类的完整有效名称父类的完整有效名称(接口和java.lang.Object除外,因为没有父类)类型修饰符直接接口的类型列表b。常量池。存储对类型常量使用的所有类型、字段和方法的符号引用。C。域信息。jvm必须在方法区保存该类型所有域的相关信息和域的声明顺序。域的相关信息包括:域名域类型域修饰符(publicprivateprotectedstaticfinalvolatiletransient...)d.方法信息。方法名方法返回类型方法参数方法修饰符方法的字节码(abstract和native除外)(由PC寄存器指向)操作数栈和方法栈帧局部变量区的大小ExceptionTablee.类的静态变量(所有对象共享一个副本)f.声明为final的类变量(所有对象共享一个副本)g.对加载类h的类加载器的引用。对Class类i的引用。方法表。j.一个例子:ClassLava{privateintspeed=5;voidflow();}ClassVolcano{publicstaticvoidmain(String[]args){Lavalava=newLava();lava.flow();}}下面我们描述main()方法*字节码如何第一条指令的执行。不同的jvm实现差异很大,这只是其中之一。为了运行该程序,您以某种方式将“Volcano”传递给jvm。有了这个名字,jvm找到类文件(Volcano.class)并读入。它从类文件中提取类型信息并将其放入方法区。jvm通过解析存储在方法区的字节码,激活了main()方法,在执行时,jvm维护了一个指向当前类(Volcano)的常量池的指针。请注意,jvm在加载Lava类之前开始执行。就像大多数jvms一样,它不会等到所有的类都加载完毕才开始执行,它只会在需要的时候加载。main()的第一条指令告诉jvm为常量池第一个条目中列出的类分配足够的内存。jvm通过指向Volcano常量池的指针找到入口,发现是对Lava类的符号引用,然后检查方法区看是否加载了lava。这个符号引用只是熔岩类的完全限定名称“熔岩”。在这里我们看到一个好的数据结构对于jvm尽快从一个名字找到一个类是多么的重要。这里jvm的实现者可以采用哈希表、搜索树等多种方式。相同的算法可以用于Class类的forName()的实现。当jvm发现有一个叫“Lava”的类还没有被加载时,它就开始寻找并加载“Lava.class”这个类文件。它从类文件中提取类型信息并将其放在方法区中。然后jvm将常量池条目的符号引用替换为直接指向方法区中的lava类的指针。以后可以利用这个指针快速找到lava类。而这个替换过程称为常量池解析(constantpoolresolution)。这里我们替换了一个本地指针。jvm终于开始为新的lava对象分配空间。这次jvm还是需要方法区的信息。它使用指向熔岩数据的指针(刚才指向火山常量池中第一个条目的指针)来找出一个熔岩对象需要多少空间。一旦jvm知道一个Lava对象需要多少空间,它就会在堆上分配空间,并将实例变量speed初始化为默认值0。如果lava的父对象也有实例变量,它也会被初始化。当对新生成的lava对象的引用被压入堆栈时,第一条指令也结束了。以下指令使用此引用来激活java代码以将速度变量设置为其初始值5。另一条指令将使用此引用来激活Lava对象的flow()方法。(3)堆。在运行时存储所有对象和数组。(4)堆栈。每次启动一个新线程时,都会分配一个堆栈。(5)PC寄存器(程序计数器)总是指向线程接下来要执行的指令。指令的位置放在方法区的方法字节码中。内容是相对于第一条指令的偏移量。(6)本地方法栈。让我们一起为振兴中国软件产业而努力!原文链接:http://www.cnblogs.com/huaihai/archive/2011/11/09/2242010.html【小编推荐】JVM崩溃的原因及解决方法Java技巧优化合集Java中Error和Exception的区别深入JVM第二种锁机制:Lock深入JVM锁机制之一:synchronized