JVM(Java虚拟机)充当运行Java应用程序的运行时引擎。JVM实际上是调用java代码中存在的main方法的。JVM是JRE(Java运行时环境)的一部分。
Java应用程序称为WORA(Write Once Run Anywhere)。这意味着程序员可以在一个系统上开发Java代码,并且可以期望它在任何其他支持Java的系统上运行而无需任何调整。由于JVM,这一切都是可能的。
当我们编译.java文件时,Java编译器会生成.jlass文件中包含相同类名的.class文件(包含字节代码)。当我们运行它时,这个.class文件会进入各个步骤。这些步骤一起描述了整个JVM。
类加载器子系统
它主要负责三个活动。
- 载入中
- 链接
- 初始化
加载:类加载器读取.class文件,生成相应的二进制数据并将其保存在方法区域中。对于每个.class文件,JVM在方法区域中存储以下信息。
- 加载类及其直接父类的完全限定名称。
- 无论的.class文件与类或接口或枚举
- 修改器,变量和方法信息等
加载.class文件后,JVM会创建一个Class类型的对象,以在堆内存中表示此文件。请注意,此对象的类型为java.lang包中预定义的类。程序员可以使用这个Class对象来获取类级别信息,如类名,父名,方法和变量信息等。要获得此对象引用,我们可以使用Object类的getClass()方法。
filter_none
编辑
play_arrow
brightness_5
|
输出:
Student
getName
setName
getRoll_no
setRoll_no
name
roll_No
注意:对于每个加载的.class文件,只创建一个 Class对象。
学生s2 =新学生();
// c2将指向
// c1指向的同一对象
Class c2 = s2.getClass();
的System.out.println(C1 == C2); //真的
链接:执行验证,准备和(可选)解决方案。
- 验证:它确保.class文件的正确性,即它检查此文件是否正确格式化并由有效编译器生成。如果验证失败,我们会得到运行时异常java.lang.VerifyError。
- 准备:JVM为类变量分配内存并将内存初始化为默认值。
- 解决方案:这是使用直接引用替换类型的符号引用的过程。通过搜索方法区域来定位引用的实体来完成。
初始化:在此阶段,所有静态变量都分配有在代码和静态块(如果有)中定义的值。这在类中从上到下执行,在类层次结构中从父到子执行。
一般来说,有三个类加载器:
- Bootstrap类加载器:每个JVM实现必须有一个引导类加载器,能够加载受信任的类。它加载JAVA_HOME / jre / lib目录中的核心Java API类。此路径通常称为引导路径。它以C,C ++等本地语言实现。
- 扩展类加载器:它是bootstrap类加载器的子代。它加载扩展目录JAVA_HOME / jre / lib / ext(扩展路径)中存在的类或java.ext.dirs系统属性指定的任何其他目录。它由sun.misc.Launcher $ ExtClassLoader类在java中实现。
- 系统/应用程序类加载器:扩展类加载器的子代。它负责从应用程序类路径加载类。它在内部使用映射到java.class.path的Environment Variable。它也是由sun.misc.Launcher $ AppClassLoader类在Java中实现的。
filter_none
编辑
play_arrow
brightness_5
|
输出:
null
sun.misc.Launcher$AppClassLoader@73d16e93
注意: JVM遵循委托 - 层次结构原则来加载类。系统类加载器委托加载请求到扩展类加载器和扩展类加载器委托请求到引导程序类加载器。如果在boot-strap路径中找到类,则加载类,否则请求再次转移到扩展类加载器,然后再转移到系统类加载器。最后,如果系统类加载器无法加载类,那么我们得到运行时异常java.lang.ClassNotFoundException。
JVM Memory
Method区域:在方法区域中,存储所有类级信息,如类名,直接父类名,方法和变量信息等,包括静态变量。每个JVM只有一个方法区域,它是一个共享资源。
堆区域:所有对象的信息存储在堆区域中。每个JVM还有一个堆区域。它也是一种共享资源。
堆栈区域:对于每个线程,JVM创建一个存储在此处的运行时堆栈。该堆栈的每个块都称为激活记录/堆栈帧,用于存储方法调用。该方法的所有局部变量都存储在相应的框架中。线程终止后,它的运行时堆栈将被JVM销毁。它不是共享资源。
PC寄存器:存储线程当前执行指令的地址。显然每个线程都有单独的PC寄存器。
本机方法堆栈:对于每个线程,都会创建单独的本机堆栈。它存储本机方法信息。
执行引擎
执行引擎执行.class(字节码)。它逐行读取字节码,使用各种存储区中的数据和信息并执行指令。它可分为三个部分: -
- 解释器:它逐行解释字节码然后执行。这里的缺点是,当多次调用一个方法时,每次都需要解释。
- 即时编译器(JIT):它用于提高解释器的效率。它编译整个字节码并将其更改为本机代码,因此每当解释器看到重复的方法调用时,JIT就会为该部分提供直接的本机代码,以便重新解释不需要,因此提高了效率。
- 垃圾收集器:它会销毁未引用的对象。有关垃圾收集器的更多信息,请参阅垃圾收集器。
Java Native Interface(JNI):
它是一个与Native方法库交互并提供执行所需的本机库(C,C ++)的接口。它使JVM能够调用C / C ++库并由C / C ++库调用,这些库可能是特定于硬件的。
本机方法库:
它是执行引擎所需的本机库(C,C ++)的集合。