JDK、JRE、JVM,是什麼關係?

小傅哥發表於2020-12-24


作者:小傅哥
部落格:https://bugstack.cn
Github:https://github.com/fuzhengwei/CodeGuide/wiki

沉澱、分享、成長,讓自己和他人都能有所收穫!?

一、前言

截至到這已經寫了22篇面經手冊,你看了多少?

?其實小傅哥就是藉著面經的幌子在講 Java 核心技術,探索這些核心知識點面試的背後到底在問什麼。

想問一些面試官,是因為大家都在問所以你問,還是你想從這裡問出什麼? 其實可能很多面試官如果不瞭解這些技術,往往會被求職者的答案擊碎內心,哈哈哈哈哈哈。比如:梅森旋轉演算法開放定址斐波那契雜湊啟發式清理Javassist代理方式擾動函式雜湊一致等等。

記住,讓懂了就是真的懂,比看水文、背答案要爽的多!嗯,就是有時候燒腦!

二、面試題

謝飛機,小記!,也不知道咋了,總感覺有些面試攻擊性不大,但侮辱性極強

面試官:謝飛機寫過 Java 嗎?

謝飛機:那當然寫過,寫了3年多了!

面試官:那,JDKJREJVM 之間是什麼關係?

謝飛機:嗯 J J J,JDK 裡面有 JRE,JVM 好像在 JRE 裡!?

面試官:那,Client模式、Server模式是啥?

謝飛機:嗯!?啥?

面試官:好吧,問個簡單的。JVM 是如何工作的?背答案了嗎?

謝飛機:再見,面試官!

三、JDK、JRE、JVM

1. Java 平臺標準(JDK 8)

Oracle has two products that implement Java Platform Standard Edition (Java SE) 8: Java SE Development Kit (JDK) 8 and Java SE Runtime Environment (JRE) 8.

JDK 8 is a superset of JRE 8, and contains everything that is in JRE 8, plus tools such as the compilers and debuggers necessary for developing applets and applications. JRE 8 provides the libraries, the Java Virtual Machine (JVM), and other components to run applets and applications written in the Java programming language. Note that the JRE includes components not required by the Java SE specification, including both standard and non-standard Java components.

The following conceptual diagram illustrates the components of Oracle's Java SE products:

Description of Java Conceptual Diagram

Java Platform Standard Edition 8 Documentation

關於 JDK、JRE、JVM 之間是什麼關係,在 Java 平臺標準中已經明確定義了。也就是上面的英文介紹部分。

  • Oracle 有兩個 Java 平臺標準的產品,Java SE 開發工具包(JDK) 和 Java SE 執行時環境(JRE)。
  • JDK(Java Development Kit Java開發工具包),JDK是提供給Java開發人員使用的,其中包含了java的開發工具,也包括了JRE。所以安裝了JDK,就不用在單獨安裝JRE了。其中的開發工具包括編譯工具(javac.exe) 打包工具(jar.exe)等。
  • JRE(Java Runtime Environment Java執行環境) 是 JDK 的子集,也就是包括 JRE 所有內容,以及開發應用程式所需的編譯器和偵錯程式等工具。JRE 提供了庫、Java 虛擬機器(JVM)和其他元件,用於執行 Java 程式語言、小程式、應用程式。
  • JVM(Java Virtual Machine Java虛擬機器),JVM可以理解為是一個虛擬出來的計算機,具備著計算機的基本運算方式,它主要負責把 Java 程式生成的位元組碼檔案,解釋成具體系統平臺上的機器指令,讓其在各個平臺執行。

綜上,從這段官網的平臺標準介紹和概念圖可以看出,我們執行程式的 JVM 是已經安裝到 JDK 中,只不過可能你開發了很久的程式碼,也沒有注意過。沒有注意過的最大原因是,沒有開發過一些和 JVM 相關的元件程式碼

關於,各 JDK 版本的平臺標準,可以自行比對學習,如下:

2. JDK 目錄結構和作用

我們預設安裝完 JDK 會有 jdk1.8.0_45jre1.8.0_45,兩個資料夾。其實在 JDK 的檔案中還會有 JRE 的資料夾,他們兩個 JRE 資料夾的結構是一樣的。

JDK 目錄結構

  • bin:一堆 EXE 可執行檔案,java.exe、javac.exe、javadoc.exe,已經金鑰管理工具等。
  • db:內建了 Derby 資料庫,體積小,免安裝。
  • include:Java 和 JVM 互動的標頭檔案,例如我們 JVMTI 寫的 C++ 工程時,就需要把這個 include 包引入進去jvmti.h例如:基於jvmti設計非入侵監控
  • jre:Java 執行環境,包含了執行時需要的可執行檔案,以及執行時需要依賴的 Java 類庫和動態連結庫.so .dll .dylib
  • lib:Java 類庫,例如 dt.jar、tools.jar

那麼 jvm 在哪個資料夾呢?

jvm.dll

可能你之前並沒有注意過 jvm 原來在這裡:C:\Program Files\Java\jdk1.8.0_45\jre\bin\server

  • 這部分是整個 Java 實現跨平臺的最核心內容,由 Java 程式編譯成的 .class 檔案會在虛擬機器上執行。
  • 另外在 JVM 解釋 class 檔案時需要呼叫類庫 lib。在 JRE 目錄下有兩個資料夾 lib、bin,而 lib 就是 JVM 執行所需要的類庫。
  • jvm.dll 並不能獨立工作,當 jvm.dll 啟動後,會使用 explicit 方法來載入輔助動態連結庫一起執行。

3. JDK 是什麼?

綜上通過 Java 平臺標準JDK 的目錄結構,JDK 是 JRE 的超集,JDK 包含了 JRE 所有的開發、除錯以及監視應用程式的工具。以及如下重要的元件:

  • java – 執行工具,執行 .class 的位元組碼
  • javac– 編譯器,將字尾名為.java的原始碼編譯成字尾名為.class的位元組碼
  • javap – 反編譯程式
  • javadoc – 文件生成器,從原始碼註釋中提取文件,註釋需符合規範
  • jar – 打包工具,將相關的類檔案打包成一個檔案
  • jdb – debugger,除錯工具
  • jps – 顯示當前java程式執行的程式狀態
  • appletviewer – 執行和除錯applet程式的工具,不需要使用瀏覽器
  • javah – 從Java類生成C標頭檔案和C原始檔。這些檔案提供了連線膠合,使 Java 和 C 程式碼可進行互動。
  • javaws – 執行 JNLP 程式
  • extcheck – 一個檢測jar包衝突的工具
  • apt – 註釋處理工具
  • jhat – java堆分析工具
  • jstack – 棧跟蹤程式
  • jstat – JVM檢測統計工具
  • jstatd – jstat守護程式
  • jinfo – 獲取正在執行或崩潰的java程式配置資訊
  • jmap – 獲取java程式記憶體對映資訊
  • idlj – IDL-to-Java 編譯器. 將IDL語言轉化為java檔案
  • policytool – 一個GUI的策略檔案建立和管理工具
  • jrunscript – 命令列指令碼執行
  • appletviewer:小程式瀏覽器,一種執行HTML檔案上的Java小程式的Java瀏覽器

4. JRE 是什麼?

JRE 本身也是一個執行在 CPU 上的程式,用於解釋執行 Java 程式碼。

一般像是實施的工作,會在客戶現場安裝 JRE,因為這是執行 Java 程式的最低要求。

JRE 目錄結構 lib、bin

  • bin:有 java.exe 但沒有 javac.exe。也就是無法編譯 Java 程式,但可以執行 Java 程式,可以把這個bin目錄理解成JVM。
  • lib:Java 基礎&核心類庫,包含 JVM 執行時需要的類庫和 rt.jar。也包含用於安全管理的檔案,這些檔案包括安全策略(security policy)和安全屬性(security properties)等。

5. JVM 是什麼?

其實簡單說 JVM 就是執行 Java 位元組碼的虛擬機器,JVM 是一種規範,各個供應商都可以實現自己 JVM虛擬機器。就像小傅哥自己也按照虛擬機器規範和手寫JVM的相關書籍實現了,基於Java實現的JVM虛擬機器。

用Java實現JVM原始碼

原始碼地址https://github.com/fuzhengwei/itstack-demo-jvm
內容簡介:本程式碼主要介紹如何通過 java 程式碼來實現 JVM 的基礎功能(搜尋解析class檔案、位元組碼命令、執行時資料區等),從而讓java程式設計師通過最熟知的java程式,學習JVM是如何將java程式一步步跑起來的。

當然,我們下載 Oracle 公司的 JVM 與自己實現的相比,要高階的多。他們的設計有不斷優化的記憶體模型、GC回收策略、自適應優化器等。

另外,JVM 之所以稱為虛擬機器,主要就是因為它為了實現 “write-once-run-anywhere”。提供了一個不依賴於底層作業系統和機器硬體結構的執行環境。

5.1 Client模式、Server模式

在 JVM 中有兩種不同風格的啟動模式, Client模式、Server模式。

  • Client模式:載入速度較快。可以用於執行GUI互動程式。
  • Server模式:載入速度較慢但執行起來較快。可以用於執行伺服器後臺程式。

修改配置模式檔案:C:\Program Files\Java\jre1.8.0_45\lib\amd64\jvm.cfg

# List of JVMs that can be used as an option to java, javac, etc.
# Order is important -- first in this list is the default JVM.
# NOTE that this both this file and its format are UNSUPPORTED and
# WILL GO AWAY in a future release.
#
# You may also select a JVM in an arbitrary location with the
# "-XXaltjvm=<jvm_dir>" option, but that too is unsupported
# and may not be available in a future release.
#
-server KNOWN
-client IGNORE
  • 如果需要調整,可以把 client 設定為 KNOWN,並調整到 server 前面。
  • JVM 預設在 Server模式下,-Xms128M、-Xmx1024M
  • JVM 預設在 Client 模式下,-Xms1M、-Xmx64M

5.2 JVM 結構和執行器

這部分屬於 JVM 的核心知識,但不是本篇重點,會在後續的章節中陸續講到。本章只做一些介紹。

  • Class Loader:類裝載器是用於載入類檔案的一個子系統,其主要功能有三個:loading(載入),linking(連結),initialization(初始化)。
  • JVM Memory Areas:方法區、堆區、棧區、程式計數器。
  • Interpreter(直譯器):通過查詢預定義的 JVM 指令到機器指令對映,JVM 直譯器可以將每個位元組碼指令轉換為相應的本地指令。它直接執行位元組碼,不執行任何優化。
  • JIT Compiler(即時編譯器):為了提高效率,JIT Compiler 在執行時與 JVM 互動,並適當將位元組碼序列編譯為本地機器程式碼。典型地,JIT Compiler執行一段程式碼,不是每次一條語句。優化這塊程式碼,並將其翻譯為優化的機器程式碼。JIT Compiler是預設開啟

四、總結

  • 這篇的知識並不複雜,涉及的面試內容也較少,更多的是對接下來要講到 JVM 相關面試內容的一個開篇介紹,為後續的要講的內容做一個鋪墊。
  • 如果你在此之前沒有關注過JDK、JRE、JVM的結構和相應的元件配置以及執行模式,那麼可以在此基礎上繼續學習加深印象。另外想深入學習JVM並不太容易,既要學習JVM規範也要上手應用實踐,所以很建議先手寫JVM,再實踐驗證JVM。
  • 好了,本章節就扯到這了。這些知識點即使分享給大家,也是我自己學習、收錄、整理、驗證的過程。互相學習、互相成長,如果有錯誤之處,直接留言給我,我會不斷的改正。大家一起進步!

五、系列推薦

相關文章