JVM(Java Virtual Machine):它是一个引擎,为Java应用程序提供运行时环境,并负责转换通过编译(.java文件)生成的字节码(.class文件)。JVM 是 Java 运行时环境 (JRE) 的一部分。
Java 应用程序称为 WORA(Write Once Run Anywhere)。这意味着程序员可以在一个系统上开发 Java 代码,并且可以期望它无需任何调整就可以在任何其他支持 Java 的系统上运行。由于 JVM,这一切都是可能的。
ClassLoader 是 Java 运行时环境 (JRE) 的一部分,可将 Java 类文件从文件系统、网络或任何其他来源动态加载到 Java 虚拟机中。它分为三个主要阶段:
是负责从各种资源(例如文件系统、jar 文件、网络套接字)将字节代码(.class 文件)加载到内存中的部分。
Load阶段涉及三种不同类型的ClassLoader:
当JVM 请求一个类时,它通过传递类的完全分类名称来调用java.lang.ClassLoader 类的loadClass() 方法。loadClass() 方法调用 findLoadedClass() 方法来检查该类是否已经加载。需要避免多次加载类。
如果该类未加载,它将请求委托给父 ClassLoader 以加载该类。如果 ClassLoader 没有找到类,它会调用 findClass() 方法在文件系统中查找类。下图显示了 ClassLoader 如何使用委托在 Java 中加载类。
假设我们有一个特定于应用程序的类 Student.class。加载此类文件的请求将传输到 Application ClassLoader。它委托给它的父扩展类加载器。此外,它委托给 Bootstrap ClassLoader。Bootstrap 在 rt.jar 中搜索该类,因为该类不存在。现在请求传输到 Extension ClassLoader,它搜索目录 jre/lib/ext 并尝试在其中找到此类。如果在此处找到该类,Extension ClassLoader 将加载该类。Application ClassLoader 从不加载该类。当扩展 ClassLoader 不加载它时,Application ClaasLoader 从 Java 中的 CLASSPATH 加载它。
可见性原则是说子ClassLoader可以看到父ClassLoader加载的类,反之则不然。这意味着如果 Application ClassLoader 加载 Student.class,在这种情况下,尝试使用 Extension ClassLoader 显式加载 Student.class 会抛出
java.lang.ClassNotFoundException。
主要分为三个阶段:
JVM 指令 anewarray、checkcast、getfield、getstatic、instanceof、invokedynamic、invokeinterface、invokespecial、invokestatic、invokevirtual、ldc、ldc_w、multiawarray、new、putfield 和 putstatic 对运行时常量池进行符号引用 。执行这些指令中的任何一条都需要解析其符号引用。
这是类加载的最后阶段,这里所有的静态变量都将被赋予原始值,并执行静态块。
Java 虚拟机有一个 在所有 Java 虚拟机线程之间共享的方法区。方法区类似于常规语言的编译代码的存储区,或者类似于操作系统进程中的“文本”段。它存储每个类的结构,例如运行时常量池、字段和方法数据,以及方法和构造函数的代码,包括类和实例初始化以及接口初始化中使用的特殊方法。
Java 虚拟机有一个 在所有 Java 虚拟机线程之间共享的堆。堆是运行时数据区域,从中分配所有类实例和数组的内存。
堆是在虚拟机启动时创建的。对象的堆存储由自动存储管理系统(称为 垃圾收集器)回收;对象永远不会显式释放。Java 虚拟机没有假定特定类型的自动存储管理系统,可以根据实现者的系统要求选择存储管理技术。堆可以是固定大小的,也可以根据计算的需要进行扩展,如果不需要更大的堆,则可以收缩。堆的内存不需要是连续的。
Java 虚拟机实现可以让程序员或用户控制堆的初始大小,如果堆可以动态扩展或收缩,还可以控制最大和最小堆大小。
以下异常情况与堆相关联:
每个 Java 虚拟机线程都有一个私有的 Java 虚拟机堆栈,与线程同时创建。Java 虚拟机堆栈存储帧。Java 虚拟机堆栈类似于 C 等常规语言的堆栈:它保存局部变量和部分结果,并在方法调用和返回中发挥作用。因为 Java 虚拟机堆栈从不直接操作,除了压入和弹出帧外,帧可能是堆分配的。Java 虚拟机堆栈的内存不需要是连续的。
在The Java® Virtual Machine Specification第一版中 ,Java 虚拟机堆栈被称为 Java 堆栈。
此规范允许 Java 虚拟机堆栈具有固定大小或根据计算需要动态扩展和收缩。如果 Java 虚拟机堆栈的大小是固定的,则每个 Java 虚拟机堆栈的大小可以在创建该堆栈时独立选择。
Java 虚拟机实现可以为程序员或用户提供对 Java 虚拟机堆栈初始大小的控制,以及在动态扩展或收缩 Java 虚拟机堆栈的情况下,对最大和最小大小的控制。
以下异常情况与 Java 虚拟机堆栈相关:
它存储当前执行的指令的地址。
Native Method Stack 保存本地方法信息。对于每个线程,都会创建一个单独的本机方法堆栈。
执行引擎通过执行每个类中存在的代码来处理此问题。但是,在执行程序之前,需要将字节码转换为机器语言指令。JVM 可以使用解释器或 JIT 编译器作为执行引擎。
它可以分为三个部分:
解释器:解释器逐行读取并执行字节码指令。由于逐行执行,解释器相对较慢。
解释器的另一个缺点是当一个方法被多次调用时,每次都需要重新解释。
即时编译器(JIT) :用于提高解释器的效率。它编译整个字节码并将其更改为本地代码,因此每当解释器看到重复的方法调用时,JIT 会为该部分提供直接的本地代码,因此不需要重新解释,从而提高了效率。
垃圾收集器:它销毁未引用的对象。有关垃圾收集器的更多信息,请参阅 Java Garbage Collection Basics。
它是一个与本地方法库交互并提供执行所需的本地库(C、C++)的接口。它使 JVM 能够调用 C/C++ 库,并被可能特定于硬件的 C/C++ 库调用。
它是执行引擎所需的本机库(C、C++)的集合。
本文链接:http://www.28at.com/showinfo-26-12337-0.htmlJVM 架构—JVM 内部是如何工作的?
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com
上一篇: 一文浅谈Mockito使用