淺談JDK、JRE、JVM區(qū)別與聯(lián)系

注釋:轉(zhuǎn)載請注明出處??嘤谀芰τ邢?,如果寫的不對的地方,請各位看官指正。

先說一下這篇博文的起因把,第一個(gè)原因想編譯一下jdk ,看一一下源碼代碼,修改一下System.out.println()也好,但這期間遇到挺多問題,才發(fā)現(xiàn)以為自己已經(jīng)理解了 jdk ,jre ,jvm 其實(shí)不然。

首先說定義,然后說理解,最后結(jié)合jdk9 以后引入的 模塊化(jigsaw) 再講解一下。

jdk ,jre ,jvm 都是jdk8 之前這樣劃分的,jdk9 之后就沒有這么明確的概念了。

顯然,這三者的關(guān)系是:一層層的嵌套關(guān)系。JDK>JRE>JVM。

image

jvm是jre的子集,jre對比jvm多了rt.jar標(biāo)準(zhǔn)包的內(nèi)容

而jre是jdk的子集,jdk對比jre多了javac等工具

一、JVM

JVM(Java Virtual Machine),即java虛擬機(jī), java運(yùn)行時(shí)的環(huán)境,JVM是一種用于計(jì)算設(shè)備的規(guī)范,它是一個(gè)虛構(gòu)出來的計(jì)算機(jī),是通過在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來實(shí)現(xiàn)的。針對java客戶端,也就是擁有可運(yùn)行的.class文件包(jar或者war)的用戶。

可能上面這個(gè)定義并不太好理解,JVM (java 虛擬機(jī)) ,回想一下當(dāng)初java引以為傲的,當(dāng)初大寫學(xué)java大吹特吹的就是”一處編譯到處運(yùn)行“、”引入了垃圾回收機(jī)制“(從C,C++的恐懼拯救出來)、面向?qū)ο缶幊獭?/strong>

問題一:現(xiàn)在假設(shè)你是出生在哪個(gè)年代的大牛,并且還沒有一種叫
爪哇的語言,你想要編寫一種”一處編譯到處運(yùn)行“、”也不用老想著
內(nèi)存釋放“的語言,你會(huì)如何做?

反轉(zhuǎn)我想到的辦法有2種:

  1. 設(shè)計(jì)一種解釋性編程語言。(執(zhí)行效率不高)

  2. 在不同平臺(tái)之間增加一層虛擬機(jī),將字節(jié)碼文件通過虛擬機(jī)針對不同平臺(tái)進(jìn)行翻譯。

于JVM就誕生了,JVM就是這個(gè)”一處編譯到處運(yùn)行“的核心,所有的java程序會(huì)首先被編譯為.class的類文件,這種類文件可以在虛擬機(jī)上執(zhí)行,class文件并不直接與機(jī)器的操作系統(tǒng)相對應(yīng),而是經(jīng)過虛擬機(jī)間接與操作系統(tǒng)交互,由虛擬機(jī)將程序解釋給本地系統(tǒng)執(zhí)行。如果用設(shè)計(jì)模式來比喻先當(dāng)于 ==橋接模式==。并且jvm 是用的是C語言+匯編語言。

二、JRE

JRE(Java Runtime Environment,Java運(yùn)行環(huán)境),包含JVM標(biāo)準(zhǔn)實(shí)現(xiàn)及Java核心類庫。JRE是Java運(yùn)行環(huán)境,并不是一個(gè)開發(fā)環(huán)境,所以沒有包含任何開發(fā)工具(如編譯器和調(diào)試器) JRE是指java運(yùn)行環(huán)境。

問題二:JVM有了,單是要設(shè)計(jì)一個(gè)什么樣的語言呢,有什么特性呢,如何能更好的抽象現(xiàn)實(shí)世界?

于是爪哇語言出現(xiàn)了,一種面向?qū)ο缶幊痰恼Z言。

那么jre 比 jvm 多了些什么呢?rt.jar,現(xiàn)在就著手定義java 關(guān)鍵字,語法,還有基礎(chǔ)類庫吧。

定義完了這些,發(fā)現(xiàn)JVM不能單獨(dú)搞定class的執(zhí)行,解釋class的時(shí)候JVM需要調(diào)用解釋所需要的基礎(chǔ)類庫lib。在JDK下面的的jre目錄里面有兩個(gè)文件夾bin和lib,在這里可以認(rèn)為bin里的就是jvm,lib中則是jvm工作所需要的類庫,而jvm和 lib和起來就稱為jre。JVM+Lib=JRE,如果講的具體點(diǎn)就是bin目錄下的jvm.dll文件, jvm.dll無法單獨(dú)工作,當(dāng)jvm.dll啟動(dòng)后,會(huì)使用explicit的方法(就是使用Win32 API之中的LoadLibrary()與GetProcAddress()來載入輔助用的動(dòng)態(tài)鏈接庫),而這些輔助用的動(dòng)態(tài)鏈接庫(.dll)都必須位 于jvm.dll所在目錄的父目錄之中。因此想使用哪個(gè)JVM,只需要設(shè)置PATH,指向JRE所在目錄下的jvm.dll

在從應(yīng)用層面說一下jre吧,就是客戶端想運(yùn)行一個(gè)編譯好的程序.jar 或者 .war 可以沒有jdk 但是沒有jre 是不行的。

三、JDK

JDK(Java Development Kit) 是整個(gè)JAVA的核心,包括了Java運(yùn)行環(huán)境(Java Runtime Envirnment),一堆Java工具(javac/java/jdb等)和Java基礎(chǔ)的類庫(即Java API 包括rt.jar)。

JDK是java開發(fā)工具包,基本上每個(gè)學(xué)java的人都會(huì)先在機(jī)器 上裝一個(gè)JDK,那他都包含哪幾部分呢?在目錄下面有 六個(gè)文件夾、一個(gè)src類庫源碼壓縮包、和其他幾個(gè)聲明文件。其中,真正在運(yùn)行java時(shí)起作用的 是以下四個(gè)文件夾:bin、include、lib、 jre。有這樣一個(gè)關(guān)系,JDK包含JRE,而JRE包 含JVM。

問題三:jvm 有了,java 語言有了,一種語言是要給程序猿用的,
只有讓猴子愉快的玩耍才能讓這個(gè)語言有強(qiáng)大的生命力,那要如果
做呢?
  1. 需要有強(qiáng)大的類庫,畢竟猴子都挺懶。

  2. 使用方便。

于是jdk 就來,里面有很多好用的類庫比如 容器類庫,寫過C只有數(shù)組就能理解List是多么的好用了。jdk就是程序庫,可以讓的的java 程序方便的引用一些實(shí)現(xiàn)好的類庫。并且發(fā)現(xiàn)javac 、 java 編譯和運(yùn)行也很方便。這樣猴子開心了,語言也有了生命力。這也就是jdk 是程序猿必備的。

四、JDK、JRE、JVM三者的聯(lián)系與區(qū)別

1.三者聯(lián)系: JVM不能單獨(dú)搞定class的執(zhí)行,解釋class的時(shí)候JVM需要調(diào)用解釋所需要的類庫lib。在JDK下面的的jre目錄里面有兩個(gè)文件夾bin和lib,在這里可以認(rèn)為bin里的就是jvm,lib中則是jvm工作所需要的類庫,而jvm和 lib和起來就稱為jre。JVM+Lib=JRE??傮w來說就是,我們利用JDK(調(diào)用JAVA API)開發(fā)了屬于我們自己的JAVA程序后,通過JDK中的編譯程序(javac)將我們的文本java文件編譯成JAVA字節(jié)碼,在JRE上運(yùn)行這些JAVA字節(jié)碼,JVM解析這些字節(jié)碼,映射到CPU指令集或OS的系統(tǒng)調(diào)用。

2.三者區(qū)別: a.JDK和JRE區(qū)別:在bin文件夾下會(huì)發(fā)現(xiàn),JDK有javac.exe而JRE里面沒有,javac指令是用來將java文件編譯成class文件的,這是開發(fā)者需要的,而用戶(只需要運(yùn)行的人)是不需要的。JDK還有jar.exe, javadoc.exe等等用于開發(fā)的可執(zhí)行指令文件。這也證實(shí)了一個(gè)是開發(fā)環(huán)境,一個(gè)是運(yùn)行環(huán)境。 b.JRE和JVM區(qū)別:JVM并不代表就可以執(zhí)行class了,JVM執(zhí)行.class還需要JRE下的lib類庫的支持,尤其是rt.jar。


時(shí)光飛逝,變化是永恒的不變的

最近看jdk11 發(fā)現(xiàn)目錄下已經(jīng)沒有jre 就比較迷惑,才引起興趣從新研究一下jdk,jre,jvm

jdk9之后的jdk,已經(jīng)模塊化了,模塊化之后,就不再區(qū)分jvm,jre和jdk了,也就是沒有jvm,jre,jdk一說了

過去jvm是jre的子集,jre對比jvm多了rt.jar標(biāo)準(zhǔn)包的內(nèi)容

而jre是jdk的子集,jdk對比jre多了javac等工具

那么9的jigsaw之后,所有這些,都被拆成了一個(gè)又一個(gè)jmod,模塊

比如java.base.jmod,jdk.javac.jmod等

那用戶可以根據(jù)自身需要,自由組合出自己的runtime,而這個(gè)runtime可能是jdk

也可能是jre+jdk的一部分,也可能是jre的一部分+jdk的一部分,或者干脆就只有jvm的一部分

而且用戶可以添加第三方提供的native擴(kuò)展,比如常見的兩個(gè)擴(kuò)展是javafx(gui)和graal(多語

言)擴(kuò)展,graal 19.3多語言擴(kuò)展將會(huì)在2019的11月19日發(fā)布,到時(shí)候你可以利用該工具擴(kuò)展出支

持javascript,python,ruby,r等語言的運(yùn)行時(shí)(runtime),javafx等下說

甚至java提供了jaotc可以將整個(gè)runtime精簡,做成binary二進(jìn)制機(jī)器碼,就跟c等語言一樣了

所以這個(gè)時(shí)候再提供jre就毫無意義了,因?yàn)檫@跟以前你拿一個(gè)jar出來,然后所有有jre的地方都能

運(yùn)行不一樣了

如果你的jar依賴的jmod不在你自己做的runtime里面,那還是運(yùn)行不了

所以就不再提供jre了,你需要的話,用jlink自己制作runtime

image

至于jdk9 模塊化編程在后面會(huì)詳細(xì)再寫一篇?,F(xiàn)在明白一個(gè)道理,覺得明白不一定真的明白,紙上得來終覺淺,絕知此事要躬行。還有一個(gè)最好的方式檢查是否真的明白,就是給別人講明白,要是有能互動(dòng)的話,別人的提問還能幫助自己可能沒想到的盲點(diǎn)。

最后一個(gè)問題啊,你們知道jre現(xiàn)在最高版本是多少嗎?

參考引用:

**[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 **

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容