Java 中的 JDK、JRE 和 JVM

这一节可以带你浅显认识一下 类加载器、解释器和JIT 编译器。在学习 Java 之初,你很难理解这些内容,但是了解一些基本概念,可以帮助你了解自己写的代码是如何工作、执行的。

Java 程序的执行

在深入了解 Java 内部之前,让我们先了解一下 Java 源文件是如何执行的。

  1. 使用编辑器或 IDE(集成开发环境),编写 java 文件(java 源代码)
  2. 解析 java 文件,确保没有基本的错误
  3. java 编译器(javac)将源代码编译成 .class 字节码文件
  4. 类文件可以通过Java虚拟机(JVM)在任意操作系统中执行
  5. JVM 将字节码转换为机器可以执行的本机机器代码

什么是JVM

Java 虚拟机(JVM) 是运行 Java 字节码的虚拟机。你可以通过将.java文件编译来获得字节码.class文件。.class文件包含 JVM 理解的字节码。

在现实世界中,JVM 是一种规范,它提供了一个可以执行 Java 字节码的运行时环境。不同的供应商提供此规范的不同实现。

JVM 最流行的实现是由 Oracle Corporation 拥有和提供的 Hotspot。(以前由 Sun Microsystems, Inc. 提供)。

JVM 使用许多高级技术为 Java 应用程序提供最佳性能,并结合了最先进的内存模型、垃圾收集器和自适应优化器。

JVM 有两种不同的类型——客户端和服务器。尽管服务器和客户端 VM 相似,但服务器 VM 已经过专门调整以最大限度地提高峰值运行速度。它旨在执行长时间运行的服务器应用程序,这些应用程序需要尽可能快的运行速度,而不是快速启动时间或较小的运行时内存占用。开发人员可以通过指定-client-server来选择自己想要的 VM。

JVM 之所以称为虚拟,是因为它提供了一个不依赖于底层操作系统和机器硬件架构的机器接口。这种与硬件和操作系统的独立性是 Java 程序“一次编写、随处运行”价值的基石。

JVM架构

类加载器

类加载器是用于加载类文件的子系统。它执行三个主要功能,即类加载、链接和初始化。

Java 中有 3 种类加载器

  • Bootstrap
  • 扩展类加载器
  • 应用程序类加载器

加载 Loading

加载类文件时,JVM 发现某个任意类的依赖项 XYZ.class。
首先引导类加载器尝试找到该类。它扫描 rt.jar JRElib文件夹中的文件。
如果未找到类,则扩展类加载器在jre\lib\ext文件夹中搜索类文件。
同样,如果未找到类,则应用程序类加载器会搜索CLASSPATH系统环境变量中的所有 Jar 文件和类。
如果任何加载器找到类,则类加载器加载类;否则 ClassNotFoundException被抛出。

我们把上述的这种查找类的方式称之为双亲委派模型

链接 Linking

在类加载器加载类之后,执行链接。一个字节码验证器将验证生成的字节码是否正确与否。如果验证失败,我们将收到验证错误。它还为类中的静态变量和方法执行内存分配。

初始化 Initialization

这是类加载的最后阶段,这里所有的静态变量都将被赋值为原始值,静态块将被执行。

JVM 内存区域

JVM 内部的内存区域被分成多个部分来存储特定的应用程序数据。

  • 方法区(Method Area) 是存储类结构,如元数据、常量运行时池和方法代码。
  • 存储在应用程序执行期间创建的所有对象。
  • 存储局部变量和中间结果。所有这些变量都是创建它们的线程的本地变量。每个线程都有自己的 JVM 堆栈,在创建线程时同时创建。所以所有这样的局部变量都称为线程局部变量。
  • PC 寄存器 存储当前正在执行的语句的物理内存地址。在 Java 中,每个线程都有其独立的 PC 寄存器。
  • 本地方法栈 许多低级代码是用 C 和 C++ 等语言编写的,本机方法栈保存本机代码的指令。

JVM 执行引擎

分配给 JVM 的所有代码都由执行引擎执行。执行引擎读取字节码并一一执行,它使用内置的解释器JIT 编译器 将字节码转换为机器码并执行它。

使用 JVM,解释器和编译器都生成本机代码。不同之处在于它们如何生成本机代码、优化程度以及优化的成本。

JVM 解释器

JVM 解释器通过查找预定义的 JVM 指令到机器指令的映射,几乎将每个字节码指令转换为相应的本机指令。它直接执行字节码,不执行任何优化。

即时编译器

为了提高性能,JIT 编译器在运行时与 JVM 交互,并将适当的字节码序列编译成本地机器代码。通常,JIT 编译器采用一个代码块(不是一次一个语句作为解释器),优化代码,然后将其转换为优化的机器代码。

在JIT编译器默认情况下启用。你可以禁用 JIT 编译器,在这种情况下将解释整个 Java 程序。除了诊断或解决 JIT 编译问题外,不建议禁用 JIT 编译器。

解释器和 JIT 编译器的区别

解释器逐行解释字节码并按顺序执行。这会导致性能不佳。JIT 编译器通过分析块中的代码来为这个过程添加优化,然后准备更优化的机器代码。

什么是JRE

Java运行时环境(JRE)是一个软件包,其中捆绑库和Java虚拟机,和其他组件用Java运行的应用程序。JVM 只是 JRE 发行版的一部分。

要执行任何 Java 应用程序,你需要在机器中安装 JRE。这是在任何计算机上运行 Java 应用程序的最低要求。

JRE 捆绑了以下组件:

  1. Java HotSpot客户端虚拟机使用的DLL文件。
  2. Java HotSpot服务器虚拟机使用的 DLL 文件。
  3. Java 运行时环境使用的代码库、属性设置和资源文件。例如rt.jar和charsets.jar。
  4. Java扩展文件,例如localedata.jar。
  5. 包含用于安全管理的文件。其中包括安全策略(java.policy) 和安全属性(java.security) 文件。
  6. 包含支持Applet的 Jar 文件。
  7. 包含供平台使用的TrueType 字体文件。

注意,您不能在32-bit机器上安装64-bit JRE 发行版。同样,Windows 的JRE 发行版在Linux 中也不起作用;反之亦然。

什么是JDK

JDK 是 JRE 的超集。JDK 包含 JRE 的所有内容以及用于开发、调试和监视 Java 应用程序的开发工具。当您需要开发 Java 应用程序时,就需要 JDK 。

JDK 附带的几个重要组件如下:

  • appletviewer – 此工具可用于在没有 Web 浏览器的情况下运行和调试 Java Applet
  • apt – 注释处理工具
  • extcheck – 检测 JAR 文件冲突的实用程序
  • javadoc – 文档生成器,从源代码注释自动生成文档
  • jar – 归档器,它将相关的类库打包到一个 JAR 文件中。此工具还有助于管理 JAR 文件
  • jarsigner – jar 签名和验证工具
  • javap – 类文件反汇编器
  • javaws – JNLP 应用程序的 Java Web Start 启动器
  • JConsole – Java 监控和管理控制台
  • jhat – Java 堆分析工具
  • jrunscript – Java 命令行脚本外壳
  • jstack – 打印 Java 线程的 Java 堆栈跟踪的实用程序
  • keytool – 用于操作密钥库的工具
  • policytool – 策略创建和管理工具
  • xjc – Java API for XML Binding (JAXB) API 的一部分。它接受一个 XML 模式并生成 Java 类

与 JRE 一样,JDK 也依赖于平台。

JDK、JRE 和 JVM 的区别

基于以上讨论,我们可以得出这三者之间的关系如下

JRE = JVM + 运行 Java 应用程序的库。

JDK = JRE + 开发 Java 应用程序的工具。

简而言之,如果你是编写代码的 Java 应用程序开发人员,则需要在你的机器上安装 JDK。但是,如果您只想运行用 Java 构建的应用程序,则只需在计算机中安装 JRE。

转载请注明出处:码谱记录 » Java 中的 JDK、JRE 和 JVM
标签: