多情只有春庭月,猶為離人照落花。
概述
本章主要了解JDK,JRE和JVM之間的區別。JVM是如何工作的?什么是類加載器,解釋器和JIT編譯器。還有一些面試問題。
Java程序執行過程
在深入了解Java內存區域之前,我們先了解Java源文件是如何執行的。
- 我們使用編輯器在
Simple.Java
文件中編寫源代碼。 - 程序必須編譯成字節碼。編譯器(
javac
)將源代碼編譯為Simple.class
文件。 - 此后綴為
.class
的類文件可以在任何平臺/操作系統的的JVM
(Java
虛擬機)中執行。 -
JVM
負責將字節碼轉換為機器可執行的本機機器代碼。
什么是JVM?
Java
虛擬機(JVM
)是??運行Java
字節碼的虛擬機。可以通過javax
將.java
文件編譯成.class
文件。.class
文件包含JVM
可解析的字節碼。
事實上,JVM
只是為Java
字節碼提供了運行時環境和規范。不同的廠商提供此規范的不同實現。例如,此Wiki
頁面列出了其它JVM實現。
最受歡迎的JVM
虛擬機是Oracle
公司提供的Hostspot
虛擬機,(前身是Sun Microsystems,Inc
.)。
JVM
虛擬機使用許多先進技術,結合了最新的內存模型,垃圾收集器和自適應優化器,為Java
應用程序提供了最佳性能。
JVM
虛擬機有兩種不同的模式,client
模式和server
模式。盡管server
和client
相似,但server
進行了特殊調整,以最大程度地提高峰值運行速度。它用于長時間運行的服務器應用程序,它們需要盡可能快的運行速度,而不是快速啟動或較小的運行時內存占用量。開發人員可以通過指定-client
或-server
來選擇所需的模式。
JVM
之所以稱為虛擬機,是因為它提供的API
不依賴于底層操作系統和機器硬件體系結構。這種與硬件和操作系統的獨立性是Java
程序一次寫入,隨處運行必要基礎。
JVM架構
類加載器
類加載器是用于加載類文件到JVM
中。主要分為以下三步 加載,鏈接和初始化。
- 加載
- 為了加載類,
JVM
有3種類加載器。Bootstrap
,extension
和應用程序類加載器。 - 加載類文件時,
JVM
會找到這個類的所有依賴項。 - 首先類加載會判斷當前類加載器是否存在父類,如果存在則交給父加載器加載。
-
Bootstrap
為根類加載器,Bootstrap
加載器嘗試查找該類。它掃描JRE
lib
文件夾中的rt.jar
。 - 如果找不到類,那么
extension
加載器將在jre \ lib \ ext
包中搜索類文件。 - 如果還找不到類,則應用程序類加載器將在系統的
CLASSPATH
環境變量中搜索所有Ja
r文件和類 - 任何類加載程序找到了類,則由該類加載器加載類;否則拋出
ClassNotFoundException
。
- 鏈接 : 類加載器加載類后,將執行鏈接。字節碼驗證程序將驗證生成的字節碼是否正確,如果驗證失敗,我們將收到驗證錯誤。它還會對類中的靜態變量和方法執行內存分配。
- 初始化 : 這是類加載的最后階段,此處將為所有靜態變量分配原始值,并執行靜態塊。
JVM內存區域
JVM
中的內存區域分為多個部分,以存儲應用程序數據的特定部分。
- 方法區:存儲類結構,例如類的基本信息,常量運行時池和方法代碼。
- 堆:存儲在應用程序執行期間創建的所有對象。
- 棧:存儲局部變量和中間結果。所有這些變量對于創建它們的線程都是私有的。每個線程都有自己的
JVM
棧,并在創建線程時同時創建。因此,所有此類局部變量都稱為線程局部變量。 - PC寄存器:存儲當前正在執行的語句的物理內存地址。在Java中,每個線程都有其單獨的PC寄存器。
- 本地方法區:許多底層代碼都是用C和C ++等語言編寫的。本地方法棧保存本機代碼的指令。
JVM執行引擎
分配給JVM
的所有代碼均由執行引擎執行。執行引擎讀取字節碼并一一執行。它使用兩個內置的解釋器和JIT編譯器將字節碼轉換為機器碼并執行。
使用JVM
,解釋器和編譯器均會生成本機代碼。不同之處在于它們如何生成本機代碼,其優化程度以及優化成本。
解釋器
JVM
解釋器通過查找預定義的JVM
指令到機器指令的映射,幾乎將每個字節碼指令轉換為相應的本機指令。它直接執行字節碼,不執行任何優化。
JIT編譯器
為了提高性能,JIT
編譯器在運行時與JVM
交互,并將適當的字節碼序列編譯為本地機器代碼。通常,JIT
編譯器采用一段代碼(和解釋器一次一條語句不一樣),優化代碼,然后將其轉換為優化的機器代碼。
默認情況下,JIT
編譯器處于啟用狀態。您可以禁用JIT
編譯器,在這種情況下,解釋器將要解釋整個Java
程序。除了診斷或解決JIT
編譯問題外,不建議禁用JIT
編譯器。
什么是JRE
Java
運行時環境(JRE
)是一個軟件包,它將庫(jar
)和Java
虛擬機以及其他組件捆綁在一起,以運行用Java
編寫的應用程序。JRE
只是JVM
的一部分。
要執行Java
應用程序,只需要在計算機中安裝JRE
。 這是在計算機上執行Java
應用程序都是最低要求。
JRE
包含了以下組件–
- Java HotSpot客戶端虛擬機使用的DLL文件。
- Java HotSpot服務器虛擬機使用的DLL文件。
- Java運行時環境使用的代碼庫,屬性設置和資源文件。例如rt.jar和charsets.jar。
- Java擴展文件,例如localedata.jar。
- 包含用于安全管理的文件。這些文件包括安全策略(java.policy)和安全屬性(java.security)文件。
- 包含applet支持類的Jar文件。
- 包含供平臺使用的TrueType字體文件。
JRE
可以作為JDK
的一部分下載,也可以單獨下載。JRE
與平臺有關。您可以根據您的計算機的類型(操作系統和體系結構)選擇要導入和安裝的JRE
軟件包。
比如,你不能在32
位計算機上安裝64
位JRE
。同樣,用于Windows
的JRE
發行版在Linux
上將無法運行。反之亦然。
什么是JDK
JDK
比JRE
更加全面。JDK
包含JRE
擁有的所有部門以及用于開發,調試和監視Java
應用程序的開發工具。當需要開發Java
應用程序時,需要JDK
。
JDK
附帶的幾個重要組件如下:
- appletviewer –此工具可用于在沒有Web瀏覽器的情況下運行和調試Java applet
- apt –注釋處理工具
- extcheck –一種檢測JAR文件沖突的實用程序
- javadoc –文檔生成器,可從源代碼注釋自動生成文檔
- jar –存檔程序,它將相關的類庫打包到一個JAR文件中。該工具還有助于管理JAR文件
- jarsigner – jar簽名和驗證工具javap –類文件反匯編程序
- javaws – JNLP應用程序的Java Web Start啟動器
- JConsole – Java監視和管理控制臺
- jhat – Java堆分析工具
- jrunscript – Java命令行腳本外殼
- jstack –打印Java線程的Java堆棧跟蹤的實用程序
- keytool –用于操作密鑰庫的工具
- policytool –策略創建和管理工具
- xjc – XML綁定Java API(JAXB)API的一部分。它接受XML模式并生成Java類
與JRE
一樣,JDK
也依賴于平臺。因此,在為您的計算機下載JDK
軟件包時請多加注意。
JDK,JRE和JVM之間的區別
基于以上討論,我們可以得出以下這三者之間的關系
JRE = JVM + libraries to run Java application.
JDK = JRE + tools to develop Java Application.
簡而言之,如果你是編寫代碼的Java
應用程序開發人員,則需要在計算機中安裝JDK
。但是,如果只想運行用Java
內置的應用程序,則只需要在計算機上安裝JRE
。
JDK,JRE和JVM相關的面試問題
如果你理解我們在這篇文章中討論的內容,那么面對任何面試問題都不難。不過,還是要準備好回答如下問題:
什么是JVM架構
上面已經詳細解釋過了。
Java有幾種類型的類加載器
Bootstrap
, extension
、應用程序類加載器和自定義類加載器。
類加載器是如何在Java中工作的?
類加載器會在其預定義位置掃描jar
文件和類。他們掃描路徑中的所有那些類文件,并查找所需的類。如果找到它們,則加載,鏈接并初始化類文件。
jre和jvm的區別?
JVM
是用于運行Java應用程序的運行時環境的規范。Hotspot
JVM
是規范的這樣一種實現。它加載類文件,并使用解釋器和JIT
編譯器將字節碼轉換為機器代碼并執行。
解釋器和jit編譯器的區別?
解釋器逐行解釋字節碼并順序執行。這會導致性能下降。JIT
編譯器通過分析塊中的代碼來為該過程添加優化,然后準備更多優化的機器代碼。
JDK 和 JRE下載
- JDK:https://www.oracle.com/technetwork/java/javase/downloads/index.html
- JRE https://www.oracle.com/technetwork/java/javase/downloads/server-jre8-downloads-2133154.html
??????關注微信公眾號java干貨
不定期分享干貨資料