注释:转载请注明出处。苦于能力有限,如果写的不对的地方,请各位看官指正。
先说一下这篇博文的起因把,第一个原因想编译一下jdk ,看一一下源码代码,修改一下System.out.println()也好,但这期间遇到挺多问题,才发现以为自己已经理解了 jdk ,jre ,jvm 其实不然。
首先说定义,然后说理解,最后结合jdk9 以后引入的 模块化(jigsaw) 再讲解一下。
jdk ,jre ,jvm 都是jdk8 之前这样划分的,jdk9 之后就没有这么明确的概念了。
显然,这三者的关系是:一层层的嵌套关系。JDK>JRE>JVM。
jvm是jre的子集,jre对比jvm多了rt.jar标准包的内容
而jre是jdk的子集,jdk对比jre多了javac等工具
一、JVM
JVM(Java Virtual Machine),即java虚拟机, java运行时的环境,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。针对java客户端,也就是拥有可运行的.class文件包(jar或者war)的用户。
可能上面这个定义并不太好理解,JVM (java 虚拟机) ,回想一下当初java引以为傲的,当初大写学java大吹特吹的就是”一处编译到处运行“、”引入了垃圾回收机制“(从C,C++的恐惧拯救出来)、面向对象编程。
问题一:现在假设你是出生在哪个年代的大牛,并且还没有一种叫
爪哇的语言,你想要编写一种”一处编译到处运行“、”也不用老想着
内存释放“的语言,你会如何做?
反转我想到的办法有2种:
设计一种解释性编程语言。(执行效率不高)
在不同平台之间增加一层虚拟机,将字节码文件通过虚拟机针对不同平台进行翻译。
于JVM就诞生了,JVM就是这个”一处编译到处运行“的核心,所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行,class文件并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。如果用设计模式来比喻先当于 ==桥接模式==。并且jvm 是用的是C语言+汇编语言。
二、JRE
JRE(Java Runtime Environment,Java运行环境),包含JVM标准实现及Java核心类库。JRE是Java运行环境,并不是一个开发环境,所以没有包含任何开发工具(如编译器和调试器) JRE是指java运行环境。
问题二:JVM有了,单是要设计一个什么样的语言呢,有什么特性呢,如何能更好的抽象现实世界?
于是爪哇语言出现了,一种面向对象编程的语言。
那么jre 比 jvm 多了些什么呢?rt.jar,现在就着手定义java 关键字,语法,还有基础类库吧。
定义完了这些,发现JVM不能单独搞定class的执行,解释class的时候JVM需要调用解释所需要的基础类库lib。在JDK下面的的jre目录里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和 lib和起来就称为jre。JVM+Lib=JRE,如果讲的具体点就是bin目录下的jvm.dll文件, jvm.dll无法单独工作,当jvm.dll启动后,会使用explicit的方法(就是使用Win32 API之中的LoadLibrary()与GetProcAddress()来载入辅助用的动态链接库),而这些辅助用的动态链接库(.dll)都必须位 于jvm.dll所在目录的父目录之中。因此想使用哪个JVM,只需要设置PATH,指向JRE所在目录下的jvm.dll
在从应用层面说一下jre吧,就是客户端想运行一个编译好的程序.jar 或者 .war 可以没有jdk 但是没有jre 是不行的。
三、JDK
JDK(Java Development Kit) 是整个JAVA的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工具(javac/java/jdb等)和Java基础的类库(即Java API 包括rt.jar)。
JDK是java开发工具包,基本上每个学java的人都会先在机器 上装一个JDK,那他都包含哪几部分呢?在目录下面有 六个文件夹、一个src类库源码压缩包、和其他几个声明文件。其中,真正在运行java时起作用的 是以下四个文件夹:bin、include、lib、 jre。有这样一个关系,JDK包含JRE,而JRE包 含JVM。
问题三:jvm 有了,java 语言有了,一种语言是要给程序猿用的,
只有让猴子愉快的玩耍才能让这个语言有强大的生命力,那要如果
做呢?
需要有强大的类库,毕竟猴子都挺懒。
使用方便。
于是jdk 就来,里面有很多好用的类库比如 容器类库,写过C只有数组就能理解List是多么的好用了。jdk就是程序库,可以让的的java 程序方便的引用一些实现好的类库。并且发现javac 、 java 编译和运行也很方便。这样猴子开心了,语言也有了生命力。这也就是jdk 是程序猿必备的。
四、JDK、JRE、JVM三者的联系与区别
1.三者联系: JVM不能单独搞定class的执行,解释class的时候JVM需要调用解释所需要的类库lib。在JDK下面的的jre目录里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和 lib和起来就称为jre。JVM+Lib=JRE。总体来说就是,我们利用JDK(调用JAVA API)开发了属于我们自己的JAVA程序后,通过JDK中的编译程序(javac)将我们的文本java文件编译成JAVA字节码,在JRE上运行这些JAVA字节码,JVM解析这些字节码,映射到CPU指令集或OS的系统调用。
2.三者区别: a.JDK和JRE区别:在bin文件夹下会发现,JDK有javac.exe而JRE里面没有,javac指令是用来将java文件编译成class文件的,这是开发者需要的,而用户(只需要运行的人)是不需要的。JDK还有jar.exe, javadoc.exe等等用于开发的可执行指令文件。这也证实了一个是开发环境,一个是运行环境。 b.JRE和JVM区别:JVM并不代表就可以执行class了,JVM执行.class还需要JRE下的lib类库的支持,尤其是rt.jar。
时光飞逝,变化是永恒的不变的
最近看jdk11 发现目录下已经没有jre 就比较迷惑,才引起兴趣从新研究一下jdk,jre,jvm
jdk9之后的jdk,已经模块化了,模块化之后,就不再区分jvm,jre和jdk了,也就是没有jvm,jre,jdk一说了
过去jvm是jre的子集,jre对比jvm多了rt.jar标准包的内容
而jre是jdk的子集,jdk对比jre多了javac等工具
那么9的jigsaw之后,所有这些,都被拆成了一个又一个jmod,模块
比如java.base.jmod,jdk.javac.jmod等
那用户可以根据自身需要,自由组合出自己的runtime,而这个runtime可能是jdk
也可能是jre+jdk的一部分,也可能是jre的一部分+jdk的一部分,或者干脆就只有jvm的一部分
而且用户可以添加第三方提供的native扩展,比如常见的两个扩展是javafx(gui)和graal(多语
言)扩展,graal 19.3多语言扩展将会在2019的11月19日发布,到时候你可以利用该工具扩展出支
持javascript,python,ruby,r等语言的运行时(runtime),javafx等下说
甚至java提供了jaotc可以将整个runtime精简,做成binary二进制机器码,就跟c等语言一样了
所以这个时候再提供jre就毫无意义了,因为这跟以前你拿一个jar出来,然后所有有jre的地方都能
运行不一样了
如果你的jar依赖的jmod不在你自己做的runtime里面,那还是运行不了
所以就不再提供jre了,你需要的话,用jlink自己制作runtime
至于jdk9 模块化编程在后面会详细再写一篇。现在明白一个道理,觉得明白不一定真的明白,纸上得来终觉浅,绝知此事要躬行。还有一个最好的方式检查是否真的明白,就是给别人讲明白,要是有能互动的话,别人的提问还能帮助自己可能没想到的盲点。
最后一个问题啊,你们知道jre现在最高版本是多少吗?
参考引用:
**[1] https://blog.csdn.net/ancientear/article/details/79483592 **
**[2] https://www.zhihu.com/question/352542780/answer/872011539 **
**[3] https://blog.csdn.net/ancientear/article/details/79483592 **