作者:小傅哥
博客:https://bugstack.cn
Github:https://github.com/fuzhengwei/CodeGuide/wiki
沉淀、分享、成長,讓自己和他人都能有所收獲!😄
一、前言
截至到這已經寫了22篇面經手冊,你看了多少?
😄其實小傅哥就是借着面經的幌子在講 Java 核心技術
,探索這些核心知識點面試的背后到底在問什么。
想問一些面試官,是因為大家都在問所以你問,還是你想從這里問出什么? 其實可能很多面試官如果不了解這些技術,往往會被求職者的答案擊碎內心,哈哈哈哈哈哈。比如:梅森旋轉算法
、開放尋址
、斐波那契散列
、啟發式清理
、Javassist代理方式
、擾動函數
、哈希一致
等等。
記住,讓懂了就是真的懂,比看水文、背答案要爽的多!嗯,就是有時候燒腦!
二、面試題
謝飛機,小記!
,也不知道咋了,總感覺有些面試攻擊性不大,但侮辱性極強
!
面試官:謝飛機寫過 Java 嗎?
謝飛機:那當然寫過,寫了3年多了!
面試官:那,JDK
、JRE
、JVM
之間是什么關系?
謝飛機:嗯 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
關於 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 版本的平台標准,可以自行比對學習,如下:
- Java SE 6 Documentation:https://docs.oracle.com/javase/6/docs/
- Java Platform Standard Edition 7 Documentation:https://docs.oracle.com/javase/7/docs/
- Java Platform Standard Edition 8 Documentation:https://docs.oracle.com/javase/8/docs/
2. JDK 目錄結構和作用
我們默認安裝完 JDK 會有 jdk1.8.0_45
、jre1.8.0_45
,兩個文件夾。其實在 JDK 的文件中還會有 JRE 的文件夾,他們兩個 JRE 文件夾的結構是一樣的。
- 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 原來在這里: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 程序的最低要求。
- 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虛擬機。
源碼地址: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。
- 好了,本章節就扯到這了。這些知識點即使分享給大家,也是我自己學習、收錄、整理、驗證的過程。互相學習、互相成長,如果有錯誤之處,直接留言給我,我會不斷的改正。大家一起進步!