JVM、JRE和JDK之间的区别

2025/04/26

1. 概述

在本文中,我们将通过考虑JVM、JRE和JDK的组件和用途来讨论它们之间的区别。

2. JVM

Java虚拟机(JVM)是执行Java程序的虚拟机的实现

JVM首先解释字节码,然后,它将类信息存储在内存区域中。最后,执行Java编译器生成的字节码。

它是一种抽象的计算机器,具有自己的指令集并在运行时操作各种内存区域。

JVM的组件包括:

  • 类加载器
  • 运行时数据区
  • 执行引擎

2.1 类加载器

JVM的初始任务包括加载、验证和链接字节码,类加载器负责处理这些任务。

我们有一篇专门讨论类加载器的详细文章。

2.2 运行时数据区

JVM定义了各种内存区域来执行Java程序,这些区域在运行时使用,称为运行时数据区。其中一些区域在JVM启动时创建,并在JVM退出时销毁;还有一些区域在线程创建时创建,并在线程退出时销毁。

方法区

本质上,方法区类似于已编译代码的存储区域。它存储诸如运行时常量池、字段和方法数据、方法和构造函数的代码以及完全限定的类名等结构,JVM为每个类存储这些结构。

方法区,也称为永久代空间(PermGen),在JVM启动时创建,此区域的内存不需要连续,所有JVM线程共享此内存区域。

堆区域

JVM从该区域为所有类实例和数组分配内存。

垃圾回收器(GC)负责回收对象的堆内存,GC回收对象内存的过程大致分为三个阶段,即两次Minor GC和一次Major GC。

堆内存分为三部分:

  • 伊甸园空间:它是年轻代空间的一部分,当我们创建一个对象时,JVM会从这块空间分配内存。
  • 幸存者空间:也是年轻代空间的一部分,幸存者空间存储在GC的Minor GC阶段中幸存下来的对象。
  • 永久代空间:也称为老年代空间,它用于存放长期存活的对象。基本上,年轻代对象会设置一个阈值,当达到该阈值时,这些对象就会被移动到永久代空间。

JVM在启动时会创建堆区域,JVM的所有线程共享此区域,堆区域的内存不需要连续。

栈区域

将数据存储为帧,每个帧存储局部变量、部分结果和嵌套方法调用。JVM每次创建新线程时都会创建堆栈区域,该区域对于每个线程都是私有的。

堆栈中的每个条目称为堆栈帧或活动记录,每个帧包含三部分:

  • 局部变量数组:包含方法的所有局部变量和参数。
  • 操作数栈:用作存储中间计算结果的工作空间。
  • 帧数据:用于存储部分结果、方法的返回值以及对异常表的引用,该表在发生异常时提供相应的捕获块信息。

JVM堆栈的内存不需要连续。

PC寄存器

每个JVM线程都有一个单独的PC寄存器,用于存储当前正在执行的指令的地址,如果当前正在执行的指令是本机方法的一部分,则此值未定义。

本机方法堆栈

本机方法是用Java以外的语言编写的方法。

JVM提供了调用这些本机方法的功能,本机方法栈也称为“C栈”,它们存储本机方法信息,每当本机方法被编译成机器码时,它们通常使用本机方法栈来跟踪其状态。

JVM每次创建新线程时都会创建这些堆栈,因此,JVM线程不共享此区域。

2.3 执行引擎

执行引擎使用内存区域中的信息执行指令,它包含三个部分:

解释器

一旦类加载器加载并验证了字节码,解释器就会逐行执行字节码,这种执行速度相当慢。解释器的缺点是,当一个方法被多次调用时,每次都需要重新解释。

但是,JVM使用JIT编译器来减轻这个缺点。

即时(JIT)编译器

JIT编译器在运行时将经常调用的方法的字节码编译为本机代码,因此,它负责Java程序的优化。

JVM会自动监控哪些方法正在执行,一旦某个方法符合JIT编译条件,它就会被安排编译成机器码,这种方法被称为热方法,编译成机器码的过程在单独的JVM线程中进行。

因此,它不会中断当前程序的执行,编译成机器码后,运行速度更快。

垃圾回收器

Java使用垃圾回收机制进行内存管理,垃圾回收机制会检查堆内存,识别哪些对象正在使用,哪些对象未使用,最后删除未使用的对象。

GC是一个守护线程,它可以通过System.gc()方法显式调用,但是它不会立即执行,JVM会决定何时调用GC。

2.4 Java原生接口

它充当Java代码和本机(C/C++)库之间的接口。

在某些情况下,Java本身无法满足你的应用程序的需求,例如,实现依赖于平台的功能。

在这些情况下,我们可以使用JNI来使JVM中运行的代码能够调用。相反,它允许本机方法调用JVM中运行的代码。

2.5 原生库

这些是特定于平台的库,包含本机方法的实现。

3. JRE

Java运行时环境(JRE)是用于运行Java应用程序的一组软件组件

JRE的核心组件包括:

  • Java虚拟机(JVM)的实现
  • 运行Java程序所需的类
  • 属性文件

我们在上一节讨论了JVM,这里我们将重点介绍核心类和支持文件。

3.1 引导类

我们会在jre/lib/下找到引导类,此路径也称为引导类路径,它包括:

  • rt.jar中的运行时类
  • i18n.jar中的国际化类
  • charsets.jar中的字符转换类
  • 其他

引导类加载器在JVM启动时加载这些类。

3.2 扩展类

我们可以在jre/lib/extn/中找到扩展类,它是Java平台扩展的目录,此路径也称为扩展类路径

它包含jfxrt.jar中的JavaFX运行时库,以及localedata.jar中的java.text和java.util包的语言环境数据,用户还可以将自定义jar文件添加到此目录中。

3.3 属性设置

Java平台使用这些属性设置来维护其配置,根据用途,它们位于/jre/lib/内的不同文件夹中,这些文件夹包括:

  • calendar.properties中的日历配置
  • logging.properties中的日志配置
  • net.properties中的网络配置
  • /jre/lib/deploy/中的部署属性
  • /jre/lib/management/中的管理属性

3.4 其他文件

除了上述文件和类之外,JRE还包含其他事项的文件:

  • jre/lib/security中的安全管理
  • jre/lib/applet目录下存放Applet的支持类
  • jre/lib/fonts和其他位置的字体相关文件

4. JDK

Java开发工具包(JDK)提供了开发、编译、调试和执行Java程序的环境和工具

JDK的核心组件包括:

  • JRE
  • 开发工具

我们在上面的章节中讨论了JRE。

现在,我们将重点介绍各种开发工具,让我们根据用途对这些工具进行分类。

4.1 基本工具

这些工具构成了JDK的基础,用于创建和构建Java应用程序。在这些工具中,我们可以找到用于编译、调试、归档、生成Javadocs等实用程序

它们包括:

  • javac:读取类和接口定义并将它们编译成class文件
  • java:启动Java应用程序
  • javadoc:从Java源文件生成API文档的HTML页面
  • apt:根据指定源文件集中的注解查找并执行注解处理器
  • appletviewer:使我们能够在没有Web浏览器的情况下运行Java Applet
  • jar:将Java Applet或应用程序打包成一个档案
  • jdb:用于查找和修复Java应用程序中的错误的命令行调试工具
  • javah:从Java类生成C头文件和源文件
  • javap:反汇编类文件并显示有关类文件中存在的字段、构造函数和方法的信息
  • extcheck:检测目标Java存档(JAR)文件和当前安装的扩展JAR文件之间的版本冲突

4.2 安全工具

这些包括用于操作Java密钥库的密钥和证书管理工具

Java Keystore是授权证书或公钥证书的容器,因此,Java应用程序经常使用它来进行加密、身份验证以及通过HTTPS提供服务。

此外,它们还帮助我们在系统上设置安全策略,并创建可以在生产环境中在这些策略范围内运行的应用程序。这些包括:

  • keytool:帮助管理密钥库条目,即加密密钥和证书
  • jarsigner:使用密钥库信息生成数字签名的JAR文件
  • policytool:使我们能够管理定义安装安全策略的外部策略配置文件

一些安全工具也有助于管理Kerberos票证

Kerberos是一种网络身份验证协议。

它基于票证工作,允许通过非安全网络进行通信的节点以安全的方式相互证明其身份:

  • kinit:用于获取和缓存Kerberos票证授予票证
  • ktab:管理密钥表中的主体名称和密钥对
  • klist:显示本地凭证缓存和密钥表中的条目

4.3 国际化工具

国际化是设计应用程序的过程,以便它能够在不进行工程更改的情况下适应各种语言和地区。

为此,JDK提供了native2ascii工具,此工具可以将JRE支持的字符文件转换为ASCII或Unicode转义编码的文件

4.4 远程方法调用(RMI)工具

RMI工具支持Java应用程序之间的远程通信,从而为分布式应用程序的开发提供了空间

RMI允许在一个JVM中运行的对象调用在另一个JVM中运行的对象的方法,这些工具包括:

  • rmic:使用Java远程方法协议(JRMP)或Internet Inter-Orb协议(IIOP)为远程对象生成存根、骨架和连接类
  • rmiregistry:创建并启动远程对象注册表
  • rmid:启动激活系统守护进程,这允许在Java虚拟机中注册和激活对象
  • serialver:返回指定类的序列版本UID

4.5 Java IDL和RMI-IIOP工具

Java接口定义语言(IDL)为Java平台添加了基于通用对象的请求代理架构(CORBA)功能

这些工具使分布式Java Web应用程序能够使用行业标准对象管理组(OMG)-IDL调用远程网络服务上的操作。

同样,我们可以使用Internet InterORB协议(IIOP)。

RMI-IIOP(即RMI over IIOP)允许通过RMI API进行CORBA服务器和应用程序的编程,这样,两个使用任何兼容CORBA语言编写的应用程序之间就可以通过Internet InterORB协议(IIOP)建立连接。

这些工具包括:

  • tnameserv:临时命名服务,为对象引用提供树形结构目录
  • idlj:IDL-to-Java编译器,用于为指定的IDL文件生成Java绑定
  • orbd:使客户端能够在CORBA环境中透明地定位和调用服务器上的持久对象
  • servertool:提供命令行界面,用于向ORB Daemon(orbd)注册或取消注册持久服务器,启动和关闭向ORB Daemon注册的持久服务器等

4.6 Java部署工具

这些工具有助于在Web上部署Java应用程序和Applet,它们包括:

  • pack200:使用Java gzip压缩器将JAR文件转换为pack200文件
  • unpack200:将pack200文件转换为JAR文件

4.7 Java插件工具

JDK为我们提供了htmlconverter,并且需要和Java插件配合使用

一方面,Java插件在主流浏览器和Java平台之间建立了连接,使得网站上的Applet可以在浏览器中运行。

另一方面,htmlconverter是一个将包含小程序的HTML页面转换为Java插件格式的实用程序。

4.8 Java Web Start工具

JDK自带了javaws,我们可以将它与Java Web Start结合使用。

此工具允许我们通过浏览器单击即可下载并启动Java应用程序,因此,无需运行任何安装过程。

4.9 监控和管理工具

这些都是可以用来监控JVM性能和资源消耗的优秀工具,以下是其中一些:

  • jconsole:提供图形控制台,可让你监视和管理Java应用程序
  • jps:列出目标系统上已检测的JVM
  • jstat:监控JVM统计数据
  • jstatd:监控已检测JVM的创建和终止

4.10 故障排除工具

这些是我们可以利用来解决故障排除任务的实验工具

  • info:为指定的Java进程生成配置信息
  • jmap:打印指定进程的共享对象内存映射或堆内存详细信息
  • jsadebugd:附加到Java进程并充当调试服务器
  • jstack:打印给定Java进程的Java线程的Java堆栈跟踪

5. 总结

在本文中,我们确定了JVM、JRE和JDK之间的基本区别在于它们的用法。

首先,我们描述了JVM是如何成为实际执行Java字节码的抽象计算机器的。

然后,我们解释了如何运行Java应用程序,使用JRE。

最后,我们了解了如何开发Java应用程序,使用JDK。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章