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。
Post Directory
