Java 开发工具包 (JDK)、Java 虚拟机 (JVM) 和 Java 运行时环境 (JRE) 共同构成了强大的 Java 和Jakarta EE平台组件三重奏,用于开发和运行 Java 应用程序。它们一起工作,让开发人员构建和运行 Java 程序。之前我已经介绍过JDK和JVM。 在本快速概述中,您将了解 JRE,它是 Java 的运行时环境。
实际上,运行时环境是一个旨在运行其他软件的软件。JRE作为Java的运行环境,包含Java类库、Java类加载器和Java虚拟机。在这个系统中:
- 类加载器负责正确加载类并将它们与核心Java类库连接起来。
- JVM负责确保 Java 应用程序拥有在您的设备或云环境中运行和良好运行所需的资源。
- JRE主要是这些其他组件的容器,并负责编排它们的活动。
我们将在接下来的讨论中更深入地探讨这些组件如何协同工作。
安装 JDK、JRE 和 JVM
从安装的角度来看,每当您下载 JDK时,它都会包含一个版本兼容的 JRE,并且该 JRE 将包含一个默认的 JVM。您还可以从 JDK 中单独下载 JRE,并且可以从多种 JVM 中进行选择。默认值适用于大多数实现,尤其是当您刚开始使用 Java 时。
目录
- 什么是运行时环境?
- Java运行时环境
- JRE 如何与 JVM 一起工作
- 安装和使用JRE
- JRE 的版本
- DevOps 中的 JRE
- Java 内存和 JRE
- Java应用程序监控
- 结论
什么是运行时环境?
软件程序需要执行,而要做到这一点,它需要一个运行环境。过去,大多数软件都使用操作系统(OS)作为运行环境。该程序在其所在的任何计算机内运行,并直接依赖操作系统设置来访问资源;内存、磁盘访问和网络访问等资源。Java 运行时环境改变了这一切,至少对于 Java 程序来说是这样。对于 Java 和其他基于 JVM 的语言,JRE 在操作系统和实际程序之间创建了一个中介。JRE 加载类文件并启动虚拟机(JVM),以确保在许多操作系统中以一致的形式访问内存和其他系统资源。
Java 版 WORA
当它第一次被引入时,Java 的“一次编写,随处运行”原则被认为是革命性的。如今,它已被许多软件系统采用作为规范,包括JavaScript和Python。
Java运行时环境
我们可以将软件视为位于系统硬件之上的一系列层。每一层都提供其上层将使用(和需要)的服务。Java 运行时环境产生了 JVM,它是一个运行在计算机操作系统之上的软件层,提供特定于 Java 的附加服务。图 1 说明了这种布置。
国际数据集团
图 1. Java 运行时环境生成 JVM。
JRE 平滑了操作系统的多样性,确保 Java 程序无需修改即可在几乎任何操作系统上运行。它还提供增值服务。自动内存管理是JRE最重要的服务之一,确保程序员不必手动控制内存的分配和重新分配。
简而言之,JRE 是 Java 的一种元操作系统,以及其他JVM 语言(如 Scala 和 Groovy)。这是一个典型的抽象示例,将底层操作系统抽象为运行 Java 应用程序的一致平台。
JRE 如何与 JVM 一起工作
Java虚拟机是一个运行软件系统,负责执行实时Java程序。JRE 是磁盘上的软件组件,它获取已编译的 Java 代码(该代码是使用 JDK 编译的),将其与所需的库结合起来,然后启动 JVM 来执行它。
JRE 包含 Java 程序运行所需的库和软件。例如,Java 类加载器是 JRE 的一部分。这个重要的软件将编译后的 Java 代码加载到内存中,并将代码连接到适当的 Java 类库(这个过程称为链接)。
在我刚才描述的分层视图中,JVM 是由 JRE 创建的。从包的角度来看,JRE 包含 JVM,如图 2 所示。JVM 是 JRE 的一部分 — 它是 JRE 创建的用于托管程序的活动的运行部分。JRE 获取静态资产并将它们转换为托管正在运行的程序的正在运行的 JVM。
国际数据集团
图 2. 分层架构视图显示 JRE 包含 JVM、类加载器和 Java 类库。
安装和使用JRE
虽然 JRE 有一个概念性的一面,但在现实世界中,它只是安装在计算机上的软件,其目的是运行 Java 程序。作为开发人员,您主要使用 JDK 和 JVM,因为这些是您用来开发和运行 Java 程序的平台组件。作为 Java 应用程序用户,您将更多地参与 JRE,它允许您运行这些程序。
Java 9重构了 Java 平台,因此 JRE 现在只能作为 JDK 的一部分使用。当您想要使用JLink交付消费者应用程序时,您可以将捆绑的 JRE 与您的应用程序一起交付。这样的捆绑包包含运行程序所需的所有组件。出于我们的目的,我们将在 JDK 中使用 JRE。您可以从 Oracle 的 Java SE 页面下载适合您的系统的最新 JDK 。Windows 和 macOS 具有自动安装程序,可以管理详细信息(例如设置路径)。在 Linux 上,一个不错的选择是使用SDKMan。无论如何,您都需要从命令行获取 JRE,以便可以使用该java命令。
JRE 的版本
Java 运行时环境会针对每个新版本的 Java 进行更新,其版本号与 Java 平台版本控制系统保持一致,例如 JRE 1.19 运行Java 19。
许多计算机运行为 Java SE 开发的 JRE,它能够运行任何 Java 应用程序,无论它是如何开发的。大多数移动设备都附带有适用于 Java ME 的 JRE,该 JRE 已预安装在移动设备上,并且不可供下载。展望未来,通过 JLink 与自己的 JRE 捆绑的应用程序将成为常态。
下载 JDK 后,您可以通过在命令行上键入 与包含的 JRE 进行交互 java -version,这将告诉您安装的版本。(在 POSIX 系统上,您始终可以使用命令检查安装位置which java。)
DevOps 中的 JRE
JRE 在开发阶段并不是很引人注目,它主要只是在您选择的操作系统或 IDE 中运行您的程序。它在 DevOps 和系统管理中扮演着更重要的角色,因为 JRE 用于监视和配置。
基本上,JRE 提供了用于配置和控制 Java 应用程序特性的“旋钮”。内存使用就是一个典型的例子,它是系统管理的基础。虽然内存使用始终很重要,但它在云配置中至关重要,而 DevOps 是一种基于云的构建和运行软件的方法。如果您在 DevOps 环境中工作,或者有兴趣扩展到 DevOps,那么最好了解 Java 内存如何工作以及如何在 JRE 中对其进行监控。
DevOps 还是系统管理员?
DevOps是一个相对较新的术语,它描述了几十年来一直存在的东西,即开发和运营之间的互操作性。从这个意义上说,devops只是一种更新的方式来描述过去所谓的操作或系统管理。与系统管理员一样,devops 的一个重要方面是管理执行软件所需的系统。管理 JRE 是管理运行 Java 应用程序的系统的一部分。
Java 内存和 JRE
Java 内存由三个部分组成:堆、栈和元空间(以前称为 permgen)。
- 元空间是 Java 保存程序不变信息(如类定义)的地方。
- 堆空间是Java保存变量内容的地方。
- 栈空间是Java存储函数执行和变量引用的地方。
Java 8 以来的 Java 内存管理
在 Java 8 之前,元空间被称为permgen。除了是一个更酷的名字之外,元空间对于开发人员与 Java 内存空间交互的方式也是一个重大改变。以前,您可以使用该命令java -XX:MaxPermSize来监视 permgen 空间的大小。从 Java 8 开始,Java 会自动增加元空间的大小,以满足程序的元需求。Java 8 还引入了一个新标志 ,MaxMetaspaceSize您可以使用它来限制元空间大小。
配置堆空间
堆空间是Java内存系统中最动态的部分。您可以使用-Xms和-Xmx标志来告诉 Java 启动堆有多大,以及允许它变成多大。了解如何根据特定程序需求调整这些标志是 Java 内存管理的一个重要方面。理想的情况是使堆足够大以获得最有效的垃圾收集。也就是说,您希望留出足够的内存来让程序运行,但又不希望内存过大。
配置堆栈空间
堆栈空间是函数调用和变量引用排队的地方。堆栈空间是Java 编程中第二个最臭名昭著的异常的来源:StackOverflowError(第一个是 NullPointerException )。堆栈溢出异常表明您已经用完了堆栈空间,因为保留了太多堆栈空间。通常,当一个或多个方法以循环方式相互调用时,就会出现堆栈溢出,从而将越来越多的函数调用投入到堆栈中。
您可以使用-Xss开关来配置堆栈起始大小。然后堆栈根据程序的需要动态增长。
Java应用程序监控
虽然应用程序监视是 JVM 的一项功能,但 JRE 提供了配置选项,这是监视的必要基线。有多种工具可用于监控 Java 应用程序,从经典工具(如 Unix 命令top)到复杂的远程监控解决方案(如 Oracle 基础设施监控)。
在这些选项之间是可视化分析器,例如VisualVM,它允许检查正在运行的 JVM。这些工具可以跟踪热点和内存泄漏,以及监视系统中的总体内存消耗。
结论
Java 运行时环境是加载 Java 应用程序以供 JVM 执行的磁盘上程序。下载JDK时默认包含一个JRE,每个JRE都包含核心Java类库、Java类加载器和JVM。了解 JVM、JDK 和 JRE 如何交互很有帮助,尤其是在云和 DevOps 环境中工作时。在这些环境中,JRE 在监视和配置方面比在传统 Java 应用程序开发中发挥更强大的作用。