JVM(Java虚拟机)充当运行Java应用程序的运行时引擎。JVM是真正调用 主要的 方法出现在java代码中。JVM是JRE(Java运行时环境)的一部分。
Java应用程序被称为WORA(一次写入,在任何地方运行)。这意味着程序员可以在一个系统上开发Java代码,并且可以期望它在任何其他支持Java的系统上运行,而无需进行任何调整。由于JVM,这一切都是可能的。
当我们编译一个 JAVA 文件 班 中存在具有相同类名的文件(包含字节码) JAVA 文件由Java编译器生成。这 班 文件在运行时会分为不同的步骤。这些步骤一起描述了整个JVM。
类加载器子系统
它主要负责三项活动。
- 加载
- 连接
- 初始化
加载: 类加载器读取“。 “阶级” 文件,生成相应的二进制数据并将其保存在方法区域。“每个人” “班级” JVM在方法区域中存储以下信息。
- 加载的类及其直接父类的完全限定名。
- 是否 “班级” 文件与类、接口或枚举相关。
- 修饰符、变量和方法信息等。
加载“后” “班级” JVM创建一个Class类型的对象,在堆内存中表示这个文件。请注意,此对象属于中预定义的类类型 JAVA朗 包裹程序员可以使用这些类对象来获取类级别的信息,比如类的名称、父名称、方法和变量信息等。为了获取这个对象引用,我们可以使用 getClass() 方法 对象 班
JAVA
// A Java program to demonstrate working // of a Class type object created by JVM // to represent .class file in memory. import java.lang.reflect.Field; import java.lang.reflect.Method; // Java code to demonstrate use // of Class object created by JVM public class Test { public static void main(String[] args) { Student s1 = new Student(); // Getting hold of Class // object created by JVM. Class c1 = s1.getClass(); // Printing type of object using c1. System.out.println(c1.getName()); // getting all methods in an array Method m[] = c1.getDeclaredMethods(); for (Method method : m) System.out.println(method.getName()); // getting all fields in an array Field f[] = c1.getDeclaredFields(); for (Field field : f) System.out.println(field.getName()); } } // A sample class whose information // is fetched above using its Class object. class Student { private String name; private int roll_No; public String getName() { return name; } public void setName(String name) { this .name = name; } public int getRoll_no() { return roll_No; } public void setRoll_no( int roll_no) { this .roll_No = roll_no; } } |
Student getName setName getRoll_no setRoll_no name roll_No
注: 对于每一个加载” “班级” 只有文件 一 类的对象被创建。
Student s2 = new Student(); // c2 will point to same object where // c1 is pointing Class c2 = s2.getClass(); System.out.println(c1==c2); // true
链接: 执行验证、准备和(可选)解决。
- 验证 :它确保了数据的正确性 班 文件,即检查该文件是否正确格式化,是否由有效的编译器生成。如果验证失败,我们将得到运行时异常 JAVAlang.VerifyError .此活动由组件字节码验证程序完成。完成此活动后,类文件就可以进行编译了。
- 准备 :JVM为类变量分配内存,并将内存初始化为默认值。
- 决议 :将类型中的符号引用替换为直接引用的过程。通过搜索方法区域来定位引用的实体。
初始化: 在这个阶段,所有静态变量都被分配了它们在代码和静态块(如果有的话)中定义的值。这在类中从上到下执行,在类层次结构中从父级到子级执行。 一般来说,有三类装载机:
- 引导类装入器 :每个JVM实现都必须有一个引导类加载器,能够加载受信任的类。它加载“中的核心java API类” JAVA_HOME/jre/lib“ 目录该路径通常被称为引导路径。它是用C语言、C++语言等语言实现的。
- 扩展类加载器 :它是引导类加载器的子级。它加载扩展目录中的类“ JAVA_HOME/jre/lib/ext“ (扩展路径)或java指定的任何其他目录。ext.dirs系统属性。它由 太阳杂项。Launcher$ExtClassLoader 班
- 系统/应用程序类加载器 :它是扩展类加载器的子级。它负责从应用程序类路径加载类。它在内部使用映射到java的环境变量。班路径它也由 太阳杂项。Launcher$AppClassLoader 班
JAVA
// Java code to demonstrate Class Loader subsystem public class Test { public static void main(String[] args) { // String class is loaded by bootstrap loader, and // bootstrap loader is not Java object, hence null System.out.println(String. class .getClassLoader()); // Test class is loaded by Application loader System.out.println(Test. class .getClassLoader()); } } |
null jdk.internal.loader.ClassLoaders$AppClassLoader@8bcc55f
注: JVM遵循委托层次原则来加载类。系统类加载器将加载请求委托给扩展类加载器,扩展类加载器将加载请求委托给引导类加载器。如果在引导路径中找到一个类,则会加载该类,否则请求会再次传输到扩展类加载程序,然后再传输到系统类加载程序。最后,如果系统类加载器未能加载类,则会出现运行时异常 JAVAlang.ClassNotFoundException .
JVM内存
- 方法区域: 在方法区域中,存储了所有类级别的信息,如类名、直接父类名、方法和变量信息等,包括静态变量。每个JVM只有一个方法区域,它是一个共享资源。
- 堆区: 所有对象的信息都存储在堆区域中。每个JVM也有一个堆区域。它也是一种共享资源。
- 堆叠区域: 对于每个线程,JVM都会创建一个存储在这里的运行时堆栈。该堆栈的每个块都称为激活记录/堆栈帧,用于存储方法调用。该方法的所有局部变量都存储在相应的框架中。线程终止后,其运行时堆栈将被JVM破坏。它不是共享资源。
- 电脑注册: 线程当前执行指令的存储地址。显然,每个线程都有单独的PC寄存器。
- 本机方法堆栈: 对于每个线程,都会创建一个单独的本机堆栈。它存储本机方法信息。
执行引擎
执行引擎执行“ “班级” (字节码)。它逐行读取字节码,使用各种内存区域中的数据和信息,并执行指令。它可以分为三个部分:
- 口译译员 :它逐行解释字节码,然后执行。这里的缺点是,当一种方法被多次调用时,每次都需要进行解释。
- 即时编译器(JIT) :用于提高翻译效率。它编译整个字节码并将其更改为本机代码,因此每当解释器看到重复的方法调用时,JIT都会为该部分提供直接的本机代码,因此不需要重新解释,从而提高效率。
- 垃圾收集器 :它会销毁未引用的对象。有关垃圾收集器的更多信息,请参阅 垃圾收集器 .
Java本机接口(JNI):
它是一个与本机方法库交互的接口,并提供执行所需的本机库(C,C++)。它使JVM能够调用C/C++库,并被特定于硬件的C/C++库调用。
本机方法库:
它是执行引擎所需的本机库(C、C++)的集合。
本文由 高拉夫·米格拉尼 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄到contribute@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。