Bootstrap

简述java中JDK、JRE和JVM的之间的关系

初学java平台,很容易搞不清楚java中的一些概念。以下简述一下本人对JDK、JRE和JVM的之间的关系:

概念

JDK(Java Development Kit)简单理解就是Java开发工具包,是java的核心所在;JRE(Java Runtime Enviroment)是Java的运行环境,JVM( java virtual machine)也就是常常听到Java虚拟机。JDK是面向开发者的,JRE是面向使用JAVA程序的用户,JVM是java实现跨平台和系统的媒介所在。

一、JDK(Java Development Kit)

JDK(Java Development Kit),即Java开发工具包,是一个编写Java应用程序的开发环境,是java的核心所在。

JDK是整个Java的核心,包括了JRE(Java运行环境),同时在jdk文件夹bin(通常我们配置jdk的环境变量的根目录)目录中包含了一些Java开发工具(例如:jconsole、javac、java、javadoc、native2ascii、jar等)。JDK=JRE+Java开发工具(编译器、反编译器、调试器等)。下面我简单介绍一下目前最常用的jdk1.8版本的目录内容。

jdk1.8目录包含:

bin:一堆exe文件,可执行的开发工具,最主要的是javac, 例如:jconsole、javac、java、javadoc、native2ascii、jar。
jre:java运行环境,包括JVM+Java基础和核心类库 。
lib:本地资源库,包含dt.jar+tools.jar的常用类库,开发依赖包。
include:java和JVM交互用的头文件。

二、JRE(Java Runtime Environment)

JRE(Java Runtime Environment),即Java运行环境,支持Java程序运行的标准环境,包含JVM标准实现及Java核心类库。 JRE中包含了Java virtual machine(JVM),runtime class libraries和Java application launcher,这些是运行Java程序的必要组件。通过它,Java的开发者才得以将自己开发的程序发布到用户手中,让用户使用。JRE=JVM+Java基础和核心类库。

jre1.8目录包含:

bin:有java.exe但没有javac.exe,无法编译Java程序,但可以运行Java程序,可以把这个bin目录理解成JVM
lib:Java基础和核心类库,如rt.jar,也包含JVM运行时需要的类库。

三、JVM(Java Virtual Machine)

JVM(Java Virtual Machine),即Java虚拟机,运行在操作系统之上,存在于内存中,与内存打交道,与硬件没有直接交互,是Java语言实现跨平台的核心。

JVM是一种抽象,虚拟出来的计算机,和实际的计算机一样,它具有指令集并使用不同的存储区域,它负责执行指令,还要管理数据,内存和寄存器,指令集,寄存器,类文件的格式,栈,垃圾回收堆,存储区等。

Java虚拟机,是JRE的一部分。它是整个java实现跨平台的最核心的部分,负责解释执行字节码文件,是可运行java字节码文件的虚拟计算机。所有平台的上的JVM向编译器提供相同的接口,而编译器只需要面向虚拟机,生成虚拟机能识别的代码,然后由虚拟机来解释执行。
JVM主要负责运行Java编译器编译后的字节码文件(*.class文件)。这些字节码只面向JVM,不同平台的JVM都是不同的,但它们都提供了相同的接口。JVM是Java程序跨平台的关键部分,只要为不同平台实现了相应的虚拟机,编译后的Java字节码就可以在该平台上运行。把字节码解释成具体平台上的机器码执行。JVM自己无法执行,必须要联合JRE中的Java基础&核心类库才能使用。

关系

上面只是一个概念上简单的区别,下面我用截图的方式来简述三者的关系。

一、层次图

通过上图可以看出JDK包含JRE,而JRE包含JVM。

首先我们了解一下字节码:

1. 什么是字节码?采用字节码的最大好处是什么
字节码:Java源代码经过虚拟机编译器编译后产生的文件(即扩展为.class的文件),它不面向任何特定的处理器,只面向虚拟机。
2. 采用字节码的好处:
Java语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以Java程序运行时比较高效,而且,由于字节码并不专对一种特定的机器,因此,Java程序无须重新编译便可在多种不同的计算机上运行。
3. java中的编译器和解释器:
Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟机器。这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口。编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行。在Java中,这种供虚拟机理解的代码叫做字节码(即扩展为.class的文件),它不面向任何特定的处理器,只面向虚拟机。每一种平台的解释器是不同的,但是实现的虚拟机是相同的。Java源程序经过编译器编译后变成字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码送给解释器,解释器将其翻译成特定机器上的机器码,然后在特定的机器上运行,这就是上面提到的Java的特点的编译与解释并存的解释。

我们都知道一个java程序的执行过程如下:

* 编译阶段:

–javac java源文件的路径

* 运行阶段:

–打开DOS命令窗口

–输入: java A

–java.exe命令会启动java虚拟机(JVM), JVM会启动类加载器Classl oader

–ClassLoader会去硬盘.上搜索A.class文件,找到该文件会将该文件装载到JVM当 中

–JVM将A.class字节码文件解释成二进制1010101001这样的数据

–然后操作系统执行二进制和底层硬件平台进行交互

二、JDK****包含JRE

JDK包含JRE,是因为Java本身编译的源代码,也需要能够被编译执行,而要被编译就必须有JRE。通过上图可以看出JDK比JRE多了java编译与反编译语言(Java Language)、调试器和java工具包(Tools&Tool APIs)。另外从下图来看,JDK包里除了JRE这个包后还有bin文件里面都是java的可执行的编译器及其工具,如java,javadoc等;此外还有lib包(java自带的工具包)这刚好对应如上层次图中的编译语言(Java Language)和java工具包(Tools&Tool APIs)。

另外,JDK安装时一般会安装独立于JDK包之外的JRE,这个包和JDK自带的JRE内容上基本一致,两套JRE运行的时候究竟运行哪一个呢,这个时候JDK中java.exe先从自身目录中找,然后父级目录中找,如果都没有就去注册表中找。事实上JDK内部的JRE一般是内嵌JRE,当我们新建本地的工程会使用它,而当我们导入外部资源的工程时,同时相应的导入外部资源(比如jar包、war包等)就会选择外部的JRE使用。

三、JRE****包含JVM

JRE包含JVM的原因是JVM就是我们常说的java虚拟机,它是整个java实现跨平台的最核心的部分,所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行,class文件并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行(计算机本身只能编译字节码文件)。

JVM又不能单独执行class文件,解释class的时候JVM需要调用解释所需要的类库lib。因此如上图所示Java把JVM放在了JRE里面,初次外JRE还包括java SE API。

总结

JDK包含JRE,而JRE包含JVM;JDK是用于java程序的开发,而JRE则是只能运行class而没有编译的功能,所编译的class文件都必须通过JVM去执行字节码文件。java的特点之一是跨平台,它不是JAVA跨平台,而是JVM跨平台,在不同的操作系统上有不同的jvm虚拟机,因jvm,java有着**“一处执行,处处执行**”的特点。

另外,对于初学java基础薄弱的同学,推荐菜鸟教程https://www.runoob.com/java进行学习。

;